This is eTextContainer.m in view mode; [Download] [Up]
///////////////////////////////////////////////////////////////////////////////
// FILENAME: eTextContainer.m
// SUMMARY: Implementation of a general container for eText regions
// SUPERCLASS: Object
// INTERFACE: None
// PROTOCOLS: None
// AUTHOR: Rohit Khare
// COPYRIGHT: (c) 1994 California Institure of Technology, eText Project
///////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION COMMENTS
// fragile. How to ensure that we have the only "live" handles to the
// various embedded objects
///////////////////////////////////////////////////////////////////////////////
// HISTORY
// 05/08/94: Created. First actual implementation.
// Late 93/4 Prototyped and tested in TextTest.app
///////////////////////////////////////////////////////////////////////////////
#import "eTextContainer.h"
@implementation eTextContainer
// id theText
// char *theChars;
// NXRunArray *theRuns;
// int nRuns, nChars;
- init
{
[super init];
theText = nil;
theChars = NULL;
theRuns = NULL;
return self;
}
- collapse:newText
{
NXSelPt start, end;
int total = 0;
NXRun *currentRun, *nextRun;
int nextRunCnt;
// cut: the contents into a copy in our members
theText = newText;
[theText getSel:&start :&end];
nChars = end.cp - start.cp;
theChars = malloc((nChars+1) * sizeof(wchar));
[theText getSubstring:theChars start:start.cp length:nChars];
if (!theChars[nChars-1]) { // this is for smartcopy/smartpaste
nChars--;
end.cp--;
}
if (!theRuns) theRuns = (NXRunArray *)NXChunkZoneMalloc(sizeof(NXRun), sizeof(NXRun), [self zone]);
theRuns->chunk.used = 0;
total = 0;
currentRun = [theText theRuns]->runs;
nRuns = nextRunCnt = 0;
while (total < end.cp) {
if ((total + currentRun->chars) > start.cp) {
// do we need to alloc more space?
if (theRuns->chunk.used == theRuns->chunk.allocated) {
theRuns=(NXRunArray *)NXChunkZoneRealloc((NXChunk *)theRuns,[self zone]);
}
theRuns->chunk.used += sizeof(NXRun);
nextRun = (theRuns->runs) + nextRunCnt++; nRuns++;
*nextRun = *currentRun;
// how many characters are in our copy?
// the current run extends from total to total+chars
// we want chars from start.cp to end.cp.
// the end points are MAX(start.cp, total) and
// MIN(total+chars, end.cp) -- and the length is the diff.
nextRun->chars= MIN(total + currentRun->chars, end.cp) -
MAX(total, start.cp);
// zero-out the info-fields so they don't get freed
currentRun->info = nil;
}
total += currentRun->chars;
currentRun++;
}
// In an undo-enabled system, we want to have a non-traceable delete:
[[theText undoManager] disableUndoRegistration];
[theText delete:self];
[[theText undoManager] reenableUndoRegistration];
return self;
}
- expand:newText
{
[[theText undoManager] disableUndoRegistration];
[theText replaceSel:theChars length:nChars runs:theRuns];
[[theText undoManager] reenableUndoRegistration];
free(theChars); theChars = NULL;
theRuns->chunk.used = 0;
theText = nil;
return self;
}
- free
{
if (theChars) free(theChars);
if (theRuns && theRuns->chunk.used != 0) {
free(theRuns);
}
return self = [super free];
}
@endThese are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.