Retain/release fixes, and tidy up

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@8337 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
nico 2000-12-16 20:17:54 +00:00
parent 4d49b570b6
commit 0e88cae678

View file

@ -107,6 +107,7 @@
- (void) dealloc - (void) dealloc
{ {
RELEASE (textContainer);
[super dealloc]; [super dealloc];
} }
@end @end
@ -331,11 +332,11 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
- (void) dealloc - (void) dealloc
{ {
RELEASE(_textContainers); RELEASE (_textContainers);
RELEASE(_containerRuns); RELEASE (_containerRuns);
RELEASE(_fragmentRuns); RELEASE (_fragmentRuns);
RELEASE(_locationRuns); RELEASE (_locationRuns);
[super dealloc]; [super dealloc];
} }
@ -343,15 +344,18 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
// //
// Setting the text storage // Setting the text storage
// //
// The set method generally should not be called directly, but you may want to override // The set method generally should not be called directly, but you may
// it. Used to get and set the text storage. The set method is called by the // want to override it. Used to get and set the text storage. The
// NSTextStorage's addTextStorageObserver/removeTextStorageObserver methods. // set method is called by the NSTextStorage's
// addTextStorageObserver/removeTextStorageObserver methods.
- (void) setTextStorage: (NSTextStorage*)aTextStorage - (void) setTextStorage: (NSTextStorage*)aTextStorage
{ {
unsigned length = [aTextStorage length]; unsigned length = [aTextStorage length];
NSRange aRange = NSMakeRange(0, length); NSRange aRange = NSMakeRange (0, length);
ASSIGN(_textStorage, aTextStorage); /* The text storage is owning us - we mustn't retain it - he is
retaining us*/
_textStorage = aTextStorage;
// force complete re - layout // force complete re - layout
[self textStorage: aTextStorage [self textStorage: aTextStorage
edited: NSTextStorageEditedCharacters | NSTextStorageEditedAttributes edited: NSTextStorageEditedCharacters | NSTextStorageEditedAttributes
@ -381,7 +385,7 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
// new one. NSTextStorage's addLayoutManager invokes NSLayoutManager's // new one. NSTextStorage's addLayoutManager invokes NSLayoutManager's
// setTextStorage method automatically, and that includes self. // setTextStorage method automatically, and that includes self.
while( (object = (NSLayoutManager*)[enumerator nextObject]) ) while ((object = (NSLayoutManager*)[enumerator nextObject]) != nil)
{ {
[_textStorage removeLayoutManager: object]; [_textStorage removeLayoutManager: object];
[newTextStorage addLayoutManager: object]; [newTextStorage addLayoutManager: object];
@ -396,15 +400,16 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
return _textContainers; return _textContainers;
} }
// Add a container to the end of the array. Must invalidate layout of all glyphs // Add a container to the end of the array. Must invalidate layout of
// after the previous last container (ie glyphs that were not previously laid out // all glyphs after the previous last container (ie glyphs that were
// because they would not fit anywhere). // not previously laid out because they would not fit anywhere).
- (void) addTextContainer: (NSTextContainer*)obj - (void) addTextContainer: (NSTextContainer*)obj
{ {
if ( [_textContainers indexOfObjectIdenticalTo: obj] == NSNotFound ) if ([_textContainers indexOfObjectIdenticalTo: obj] == NSNotFound)
{ {
[_textContainers addObject: obj]; [_textContainers addObject: obj];
[obj setLayoutManager: self]; [obj setLayoutManager: self];
// TODO: Invalidate layout
} }
} }
@ -415,6 +420,7 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
atIndex: (unsigned)index atIndex: (unsigned)index
{ {
[_textContainers insertObject: aTextContainer atIndex: index]; [_textContainers insertObject: aTextContainer atIndex: index];
// TODO: Invalidate layout
} }
// Removes the container at index from the array. Must invalidate layout of all // Removes the container at index from the array. Must invalidate layout of all
@ -428,10 +434,11 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
// Invalidating glyphs and layout // Invalidating glyphs and layout
// //
// This removes all glyphs for the old character range, adjusts the character // This removes all glyphs for the old character range, adjusts the
// indices of all the subsequent glyphs by the change in length, and invalidates // character indices of all the subsequent glyphs by the change in
// the new character range. If actualCharRange is non-NULL it will be set to // length, and invalidates the new character range. If
// the actual range invalidated after any necessary expansion. // actualCharRange is non-NULL it will be set to the actual range
// invalidated after any necessary expansion.
- (void) invalidateGlyphsForCharacterRange: (NSRange)aRange - (void) invalidateGlyphsForCharacterRange: (NSRange)aRange
changeInLength: (int)lengthChange changeInLength: (int)lengthChange
actualCharacterRange: (NSRange*)actualRange actualCharacterRange: (NSRange*)actualRange
@ -444,15 +451,17 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
} }
} }
// This invalidates the layout information (glyph location and rotation) for // This invalidates the layout information (glyph location and
// the given range of characters. If flag is YES then this range is marked // rotation) for the given range of characters. If flag is YES then
// as a hard layout invalidation. If NO, then the invalidation is soft. // this range is marked as a hard layout invalidation. If NO, then
// A hard invalid layout range indicates that layout information must be completely // the invalidation is soft. A hard invalid layout range indicates
// recalculated no matter what. A soft invalid layout range means that there // that layout information must be completely recalculated no matter
// is already old layout info for the range in question, and if the NSLayoutManager // what. A soft invalid layout range means that there is already old
// is smart enough to figure out how to avoid doing the complete relayout, it may // layout info for the range in question, and if the NSLayoutManager
// perform any optimization available. If actualCharRange is non-NULL it will be // is smart enough to figure out how to avoid doing the complete
// set to the actual range invalidated after any necessary expansion. // relayout, it may perform any optimization available. If
// actualCharRange is non-NULL it will be set to the actual range
// invalidated after any necessary expansion.
- (void) invalidateLayoutForCharacterRange: (NSRange)aRange - (void) invalidateLayoutForCharacterRange: (NSRange)aRange
isSoft: (BOOL)flag isSoft: (BOOL)flag
actualCharacterRange: (NSRange*)actualRange actualCharacterRange: (NSRange*)actualRange
@ -460,11 +469,12 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
[self _doLayout]; [self _doLayout];
} }
// Invalidates display for the glyph or character range given. For the glyph // Invalidates display for the glyph or character range given. For
// range variant any part of the range that does not yet have glyphs generated // the glyph range variant any part of the range that does not yet
// is ignored. For the character range variant, unlaid parts of the range are // have glyphs generated is ignored. For the character range variant,
// remembered and will definitely be redisplayed at some point later when the // unlaid parts of the range are remembered and will definitely be
// layout is available. Neither method actually causes layout. // redisplayed at some point later when the layout is available.
// Neither method actually causes layout.
- (void) invalidateDisplayForCharacterRange: (NSRange)aRange - (void) invalidateDisplayForCharacterRange: (NSRange)aRange
{ {
} }
@ -473,7 +483,8 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
{ {
} }
// Invalidates layout of all glyphs in container and all subsequent containers. // Invalidates layout of all glyphs in container and all subsequent
// containers.
- (void) textContainerChangedGeometry: (NSTextContainer*)aContainer - (void) textContainerChangedGeometry: (NSTextContainer*)aContainer
{ {
// find the first character in that text container // find the first character in that text container
@ -482,22 +493,23 @@ static NSComparisonResult aSort(GSIArrayItem i0, GSIArrayItem i1)
// invalidate the layout from here on // invalidate the layout from here on
[self invalidateLayoutForCharacterRange: [self invalidateLayoutForCharacterRange:
NSMakeRange(first, [_textStorage length] - first) NSMakeRange(first, [_textStorage length] - first)
isSoft: NO isSoft: NO
actualCharacterRange: NULL]; actualCharacterRange: NULL];
} }
// Called by NSTextContainer whenever its textView changes. // Called by NSTextContainer whenever its textView changes. Used to
// Used to keep notifications in synch. // keep notifications in synch.
- (void) textContainerChangedTextView: (NSTextContainer*)aContainer - (void) textContainerChangedTextView: (NSTextContainer*)aContainer
{ {
} }
// Sent from processEditing in NSTextStorage. newCharRange is the range in the // Sent from processEditing in NSTextStorage. newCharRange is the
// final string which was explicitly edited. invalidatedRange includes stuff // range in the final string which was explicitly
// which was changed as a result of attribute fixing. invalidatedRange is either // edited. invalidatedRange includes stuff which was changed as a
// equal to newCharRange or larger. Layout managers should not change the contents // result of attribute fixing. invalidatedRange is either equal to
// of the text storage during the execution of this message. // newCharRange or larger. Layout managers should not change the
// contents of the text storage during the execution of this message.
- (void) textStorage: (NSTextStorage*)aTextStorage - (void) textStorage: (NSTextStorage*)aTextStorage
edited: (unsigned)mask edited: (unsigned)mask
range: (NSRange)range range: (NSRange)range
@ -512,7 +524,7 @@ range.location, range.length, lengthChange, invalidatedRange.location,
invalidatedRange.length); invalidatedRange.length);
*/ */
int delta = 0; int delta = 0;
unsigned last = NSMaxRange(invalidatedRange); unsigned last = NSMaxRange (invalidatedRange);
if (mask & NSTextStorageEditedCharacters) if (mask & NSTextStorageEditedCharacters)
{ {
@ -529,7 +541,7 @@ invalidatedRange.length);
// the following range is soft invalidated // the following range is soft invalidated
[self invalidateLayoutForCharacterRange: [self invalidateLayoutForCharacterRange:
NSMakeRange(last, [_textStorage length] - last) NSMakeRange (last, [_textStorage length] - last)
isSoft: YES isSoft: YES
actualCharacterRange: NULL]; actualCharacterRange: NULL];
} }
@ -538,8 +550,8 @@ invalidatedRange.length);
// Turning on/off background layout // Turning on/off background layout
// //
// These methods allow you to set/query whether text gets laid out in the // These methods allow you to set/query whether text gets laid out in
// background when there's nothing else to do. // the background when there's nothing else to do.
- (void) setBackgroundLayoutEnabled: (BOOL)flag - (void) setBackgroundLayoutEnabled: (BOOL)flag
{ {
_backgroundLayout = flag; _backgroundLayout = flag;
@ -553,22 +565,25 @@ invalidatedRange.length);
// //
// Accessing glyphs // Accessing glyphs
// //
// These methods are primitive. They do not cause the bookkeeping of filling // These methods are primitive. They do not cause the bookkeeping of
// holes to happen. They do not cause invalidation of other stuff. // filling holes to happen. They do not cause invalidation of other
// stuff.
// Inserts a single glyph into the glyph stream at glyphIndex. The character // Inserts a single glyph into the glyph stream at glyphIndex. The
// index which this glyph corresponds to is given by charIndex. // character index which this glyph corresponds to is given by
// charIndex.
- (void) insertGlyph: (NSGlyph)aGlyph - (void) insertGlyph: (NSGlyph)aGlyph
atGlyphIndex: (unsigned)glyphIndex atGlyphIndex: (unsigned)glyphIndex
characterIndex: (unsigned)charIndex characterIndex: (unsigned)charIndex
{ {
} }
// If there are any holes in the glyph stream this will cause glyph generation // If there are any holes in the glyph stream this will cause glyph
// for all holes sequentially encountered until the desired index is available. // generation for all holes sequentially encountered until the desired
// The first variant raises a NSRangeError if the requested index is out of // index is available. The first variant raises a NSRangeError if the
// bounds, the second does not, but instead optionally returns a flag indicating // requested index is out of bounds, the second does not, but instead
// whether the requested index exists. // optionally returns a flag indicating whether the requested index
// exists.
- (NSGlyph) glyphAtIndex: (unsigned)index - (NSGlyph) glyphAtIndex: (unsigned)index
{ {
return NSNullGlyph; return NSNullGlyph;
@ -581,23 +596,24 @@ invalidatedRange.length);
return NSNullGlyph; return NSNullGlyph;
} }
// Replaces the glyph currently at glyphIndex with newGlyph. The character index // Replaces the glyph currently at glyphIndex with newGlyph. The
// of the glyph is assumed to remain the same (although it can, of coiurse, be set // character index of the glyph is assumed to remain the same
// explicitly if needed). // (although it can, of coiurse, be set explicitly if needed).
- (void) replaceGlyphAtIndex: (unsigned)index - (void) replaceGlyphAtIndex: (unsigned)index
withGlyph: (NSGlyph)newGlyph withGlyph: (NSGlyph)newGlyph
{ {
} }
// This causes glyph generation similarly to asking for a single glyph. // This causes glyph generation similarly to asking for a single
// It formats a sequence of NSGlyphs (unsigned long ints). It does not include // glyph. It formats a sequence of NSGlyphs (unsigned long ints). It
// glyphs that aren't shown in the result but does zero-terminate the array. // does not include glyphs that aren't shown in the result but does
// The memory passed in to the function should be large enough for at least // zero-terminate the array. The memory passed in to the function
// glyphRange.length+1 elements. The actual number of glyphs stuck into the // should be large enough for at least glyphRange.length+1 elements.
// array is returned (not counting the null-termination). // The actual number of glyphs stuck into the array is returned (not
// RM!!! check out the private method "_packedGlyphs:range:length:" if you need // counting the null-termination). RM!!! check out the private method
// to send glyphs to the window server. It returns a (conceptually) autoreleased // "_packedGlyphs:range:length:" if you need to send glyphs to the
// array of big-endian packeg glyphs. Don't use this method to do that. // window server. It returns a (conceptually) autoreleased array of
// big-endian packeg glyphs. Don't use this method to do that.
- (unsigned) getGlyphs: (NSGlyph*)glyphArray - (unsigned) getGlyphs: (NSGlyph*)glyphArray
range: (NSRange)glyphRange range: (NSRange)glyphRange
{ {
@ -609,8 +625,8 @@ invalidatedRange.length);
{ {
} }
// If there are any holes in the glyph stream, this will cause all invalid // If there are any holes in the glyph stream, this will cause all
// character ranges to have glyphs generated for them. // invalid character ranges to have glyphs generated for them.
- (unsigned) numberOfGlyphs - (unsigned) numberOfGlyphs
{ {
return 0; return 0;
@ -619,29 +635,31 @@ invalidatedRange.length);
// //
// Mapping characters to glyphs // Mapping characters to glyphs
// //
// Sets the index of the corresponding character for the glyph at the given glyphIndex. // Sets the index of the corresponding character for the glyph at the
// given glyphIndex.
- (void) setCharacterIndex: (unsigned)charIndex - (void) setCharacterIndex: (unsigned)charIndex
forGlyphAtIndex: (unsigned)glyphIndex forGlyphAtIndex: (unsigned)glyphIndex
{ {
} }
// If there are any holes in the glyph stream this will cause glyph generation // If there are any holes in the glyph stream this will cause glyph
// for all holes sequentially encountered until the desired index is available. // generation for all holes sequentially encountered until the desired
// index is available.
- (unsigned) characterIndexForGlyphAtIndex: (unsigned)glyphIndex - (unsigned) characterIndexForGlyphAtIndex: (unsigned)glyphIndex
{ {
// Currently gyphIndex is the same as character index // Currently gyphIndex is the same as character index
return glyphIndex; return glyphIndex;
} }
// These two methods can cause glyph generation. // These two methods can cause glyph generation. Returns the range of
// Returns the range of characters that generated the glyphs in the // characters that generated the glyphs in the given glyphRange.
// given glyphRange. actualGlyphRange, if not NULL, will be set to // actualGlyphRange, if not NULL, will be set to the full range of
// the full range of glyphs that the character range returned generated. // glyphs that the character range returned generated. This range may
// This range may be identical or slightly larger than the requested glyphRange. // be identical or slightly larger than the requested glyphRange. For
// For instance, if the text storage contains the unichar (o-umlaut) and // instance, if the text storage contains the unichar (o-umlaut) and
// the glyph store contains the two atomic glyphs "o" and (umlaut), and // the glyph store contains the two atomic glyphs "o" and (umlaut),
// if the glyphRange given encloses only the first or second glyph, the // and if the glyphRange given encloses only the first or second
// actualGlyphRange will be set to enclose both glyphs. // glyph, the actualGlyphRange will be set to enclose both glyphs.
- (NSRange) characterRangeForGlyphRange: (NSRange)glyphRange - (NSRange) characterRangeForGlyphRange: (NSRange)glyphRange
actualGlyphRange: (NSRange*)actualGlyphRange actualGlyphRange: (NSRange*)actualGlyphRange
{ {
@ -653,13 +671,14 @@ invalidatedRange.length);
} }
// Returns the range of glyphs that are generated from the unichars in // Returns the range of glyphs that are generated from the unichars in
// the given charRange. actualCharRange, if not NULL, will be set to the // the given charRange. actualCharRange, if not NULL, will be set to
// actual range of characters that fully define the glyph range returned. // the actual range of characters that fully define the glyph range
// This range may be identical or slightly larger than the requested // returned. This range may be identical or slightly larger than the
// characterRange. For instance, if the text storage contains the unichars // requested characterRange. For instance, if the text storage
// "o" and (umlaut) and the glyph store contains the single precomposed glyph // contains the unichars "o" and (umlaut) and the glyph store contains
// (o-umlaut), and if the charcterRange given encloses only the first or // the single precomposed glyph (o-umlaut), and if the charcterRange
// second unichar, the actualCharRange will be set to enclose both unichars. // given encloses only the first or second unichar, the
// actualCharRange will be set to enclose both unichars.
- (NSRange) glyphRangeForCharacterRange: (NSRange)charRange - (NSRange) glyphRangeForCharacterRange: (NSRange)charRange
actualCharacterRange: (NSRange*)actualCharRange actualCharacterRange: (NSRange*)actualCharRange
{ {
@ -674,34 +693,35 @@ invalidatedRange.length);
// Setting glyph attributes // Setting glyph attributes
// //
// Each NSGlyph has an attribute field, yes? // Each NSGlyph has an attribute field, yes? This method is
// This method is primitive. It does not cause any invalidation of other stuff. // primitive. It does not cause any invalidation of other stuff.
// This method also will not cause glyph generation. The glyph being set must // This method also will not cause glyph generation. The glyph being
// already be there. // set must already be there. This method is used by the
// This method is used by the NSGlyphGenerator to set attributes. It is not // NSGlyphGenerator to set attributes. It is not usually necessary
// usually necessary for anyone but the glyph generator (and perhaps the // for anyone but the glyph generator (and perhaps the typesetter) to
// typesetter) to call it. It is provided as a public method so subclassers // call it. It is provided as a public method so subclassers can
// can extend it to accept other glyph attributes. To add new glyph attributes // extend it to accept other glyph attributes. To add new glyph
// to the text system you basically need to do two things. You need to write // attributes to the text system you basically need to do two things.
// a rulebook which will generate the attributes (in rulebooks attributes are // You need to write a rulebook which will generate the attributes (in
// identified by integer tags). Then you need to subclass NSLayoutManager to // rulebooks attributes are identified by integer tags). Then you
// provide someplace to store the new attribute and to override this method // need to subclass NSLayoutManager to provide someplace to store the
// and -attribute:forGlyphAtIndex: to understand the integer tag which your // new attribute and to override this method and
// new rulebook is generating. NSLayoutManager's implementation understands // -attribute:forGlyphAtIndex: to understand the integer tag which
// the glyph attributes which it is prepared to remember. Your override // your new rulebook is generating. NSLayoutManager's implementation
// should pass any glyph attributes it does not understand up to the superclass's // understands the glyph attributes which it is prepared to remember.
// implementation. // Your override should pass any glyph attributes it does not
// understand up to the superclass's implementation.
- (void) setIntAttribute: (int)attribute - (void) setIntAttribute: (int)attribute
value: (int)anInt value: (int)anInt
forGlyphAtIndex: (unsigned)glyphIndex forGlyphAtIndex: (unsigned)glyphIndex
{ {
} }
// This returns the value for the given glyph attribute at the glyph index // This returns the value for the given glyph attribute at the glyph
// specified. Most apps will not have much use for this info but the // index specified. Most apps will not have much use for this info
// typesetter and glyph generator might need to know about certain attributes. // but the typesetter and glyph generator might need to know about
// You can override this method to know how to return any custom glyph // certain attributes. You can override this method to know how to
// attributes you want to support. // return any custom glyph attributes you want to support.
- (int) intAttribute: (int)attribute - (int) intAttribute: (int)attribute
forGlyphAtIndex: (unsigned)glyphIndex forGlyphAtIndex: (unsigned)glyphIndex
{ {
@ -711,16 +731,17 @@ invalidatedRange.length);
// //
// Handling layout for text containers // Handling layout for text containers
// //
// These methods are fairly primitive. They do not cause any kind of // These methods are fairly primitive. They do not cause any kind of
// invalidation to happen. The glyphs being set must already exist. // invalidation to happen. The glyphs being set must already exist.
// This is not a hardship since the NSTypesetter will have had to ask for // This is not a hardship since the NSTypesetter will have had to ask
// the actual glyphs already by the time it goes to set this, and asking // for the actual glyphs already by the time it goes to set this, and
// for the glyphs causes the glyph to be generated if necessary. // asking for the glyphs causes the glyph to be generated if
// Associates the given container with the given range of glyphs. This method // necessary. Associates the given container with the given range of
// should be called by the typesetter first (ie before setting line fragment // glyphs. This method should be called by the typesetter first (ie
// rect or any of the layout bits) for each range of glyphs it lays out. // before setting line fragment rect or any of the layout bits) for
// This method will set several key layout atttributes (like not shown and // each range of glyphs it lays out. This method will set several key
// draws outside line fragment) to their default values. // layout atttributes (like not shown and draws outside line fragment)
// to their default values.
- (void) setTextContainer: (NSTextContainer*)aTextContainer - (void) setTextContainer: (NSTextContainer*)aTextContainer
forGlyphRange: (NSRange)glyphRange forGlyphRange: (NSRange)glyphRange
{ {
@ -733,8 +754,8 @@ invalidatedRange.length);
} }
// All of these methods can cause glyph generation AND layout. // All of these methods can cause glyph generation AND layout.
// Returns the range of characters which have been laid into the // Returns the range of characters which have been laid into the given
// given container. This is a less efficient method than the similar // container. This is a less efficient method than the similar
// -textContainerForGlyphAtIndex:effectiveRange:. // -textContainerForGlyphAtIndex:effectiveRange:.
- (NSRange) glyphRangeForTextContainer: (NSTextContainer*)aTextContainer - (NSRange) glyphRangeForTextContainer: (NSTextContainer*)aTextContainer
{ {
@ -749,17 +770,13 @@ textContainer(s) in containerRuns.", [_containerRuns count]);
/* /*
NSLog(@"glyphRangeForTextContainer: (%d, %d)", NSLog(@"glyphRangeForTextContainer: (%d, %d)",
aNewLine->glyphRange.location, aNewLine->glyphRange.location, aNewLine->glyphRange.length); */
aNewLine->glyphRange.length);
*/
if ([aNewLine->textContainer isEqual: aTextContainer]) if ([aNewLine->textContainer isEqual: aTextContainer])
{ {
/* /*
NSLog(@"glyphRangeForWantedTextContainer: (%d, %d)", NSLog(@"glyphRangeForWantedTextContainer: (%d, %d)",
aNewLine->glyphRange.location, aNewLine->glyphRange.location, aNewLine->glyphRange.length); */
aNewLine->glyphRange.length);
*/
return aNewLine->glyphRange; return aNewLine->glyphRange;
} }
} }
@ -767,9 +784,10 @@ aNewLine->glyphRange.length);
return NSMakeRange(NSNotFound, 0); return NSMakeRange(NSNotFound, 0);
} }
// Returns the container in which the given glyph is laid and (optionally) // Returns the container in which the given glyph is laid and
// by reference the whole range of glyphs that are in that container. // (optionally) by reference the whole range of glyphs that are in
// This will cause glyph generation AND layout as needed. // that container. This will cause glyph generation AND layout as
// needed.
- (NSTextContainer*) textContainerForGlyphAtIndex: (unsigned)glyphIndex - (NSTextContainer*) textContainerForGlyphAtIndex: (unsigned)glyphIndex
effectiveRange: (NSRange*)effectiveRange effectiveRange: (NSRange*)effectiveRange
{ {
@ -789,7 +807,8 @@ aNewLine->glyphRange.length);
// //
// Handling line fragment rectangles // Handling line fragment rectangles
// //
// Associates the given line fragment bounds with the given range of glyphs. // Associates the given line fragment bounds with the given range of
// glyphs.
- (void) setLineFragmentRect: (NSRect)fragmentRect - (void) setLineFragmentRect: (NSRect)fragmentRect
forGlyphRange: (NSRange)glyphRange forGlyphRange: (NSRange)glyphRange
usedRect: (NSRect)usedRect usedRect: (NSRect)usedRect
@ -803,9 +822,10 @@ aNewLine->glyphRange.length);
[_fragmentRuns insertObject: aNewLine]; [_fragmentRuns insertObject: aNewLine];
} }
// Returns the rect for the line fragment in which the given glyph // Returns the rect for the line fragment in which the given glyph is
// is laid and (optionally) by reference the whole range of glyphs // laid and (optionally) by reference the whole range of glyphs that
// that are in that fragment. This will cause glyph generation AND layout as needed. // are in that fragment. This will cause glyph generation AND layout
// as needed.
- (NSRect) lineFragmentRectForGlyphAtIndex: (unsigned)glyphIndex - (NSRect) lineFragmentRectForGlyphAtIndex: (unsigned)glyphIndex
effectiveRange: (NSRange*)lineFragmentRange effectiveRange: (NSRange*)lineFragmentRange
{ {
@ -842,11 +862,12 @@ aNewLine->glyphRange.length);
return NSZeroRect; return NSZeroRect;
} }
// Sets the bounds and container for the extra line fragment. The extra line // Sets the bounds and container for the extra line fragment. The
// fragment is used when the text backing ends with a hard line break or when // extra line fragment is used when the text backing ends with a hard
// the text backing is totally empty to define the extra line which needs to // line break or when the text backing is totally empty to define the
// be displayed. If the text backing does not end with a hard line break this // extra line which needs to be displayed. If the text backing does
// should be set to NSZeroRect and nil. // not end with a hard line break this should be set to NSZeroRect and
// nil.
- (void) setExtraLineFragmentRect: (NSRect)aRect - (void) setExtraLineFragmentRect: (NSRect)aRect
usedRect: (NSRect)usedRect usedRect: (NSRect)usedRect
textContainer: (NSTextContainer*)aTextContainer textContainer: (NSTextContainer*)aTextContainer
@ -882,15 +903,17 @@ aNewLine->glyphRange.length);
{ {
} }
// Used to indicate that a particular glyph for some reason marks outside // Used to indicate that a particular glyph for some reason marks
// its line fragment bounding rect. This can commonly happen if a fixed // outside its line fragment bounding rect. This can commonly happen
// line height is used (consider a 12 point line height and a 24 point glyph). // if a fixed line height is used (consider a 12 point line height and
// a 24 point glyph).
- (void) setDrawsOutsideLineFragment: (BOOL)flag - (void) setDrawsOutsideLineFragment: (BOOL)flag
forGlyphAtIndex: (unsigned)glyphIndex forGlyphAtIndex: (unsigned)glyphIndex
{ {
} }
// Returns whether the glyph will make marks outside its line fragment's bounds. // Returns whether the glyph will make marks outside its line
// fragment's bounds.
- (BOOL) drawsOutsideLineFragmentForGlyphAtIndex: (unsigned)glyphIndex - (BOOL) drawsOutsideLineFragmentForGlyphAtIndex: (unsigned)glyphIndex
{ {
return NO; return NO;
@ -900,13 +923,14 @@ aNewLine->glyphRange.length);
// Layout of glyphs // Layout of glyphs
// //
// Sets the location to draw the first glyph of the given range at. // Sets the location to draw the first glyph of the given range at.
// Setting the location for a glyph range implies that its first glyph // Setting the location for a glyph range implies that its first glyph
// is NOT nominally spaced with respect to the previous glyph. When all // is NOT nominally spaced with respect to the previous glyph. When
// is said and done all glyphs in the layoutManager should have been // all is said and done all glyphs in the layoutManager should have
// included in a range passed to this method. But only glyphs which // been included in a range passed to this method. But only glyphs
// start a new nominal rtange should be at the start of such ranges. // which start a new nominal rtange should be at the start of such
// Glyph locations are given relative the their line fragment bounding rect's origin. // ranges. Glyph locations are given relative the their line fragment
// bounding rect's origin.
- (void) setLocation: (NSPoint)aPoint - (void) setLocation: (NSPoint)aPoint
forStartOfGlyphRange: (NSRange)glyphRange forStartOfGlyphRange: (NSRange)glyphRange
{ {
@ -918,14 +942,15 @@ forStartOfGlyphRange: (NSRange)glyphRange
[_locationRuns insertObject: aNewLine]; [_locationRuns insertObject: aNewLine];
} }
// Returns the location that the given glyph will draw at. If this glyph // Returns the location that the given glyph will draw at. If this
// doesn't have an explicit location set for it (ie it is part of (but not // glyph doesn't have an explicit location set for it (ie it is part
// first in) a sequence of nominally spaced characters), the location is // of (but not first in) a sequence of nominally spaced characters),
// calculated from the location of the last glyph with a location set. // the location is calculated from the location of the last glyph with
// Glyph locations are relative the their line fragment bounding rect's // a location set. Glyph locations are relative the their line
// origin (see -lineFragmentForGlyphAtIndex:effectiveRange: below for // fragment bounding rect's origin (see
// finding line fragment bounding rects). This will cause glyph generation // -lineFragmentForGlyphAtIndex:effectiveRange: below for finding line
// AND layout as needed. // fragment bounding rects). This will cause glyph generation AND
// layout as needed.
- (NSPoint) locationForGlyphAtIndex: (unsigned)glyphIndex - (NSPoint) locationForGlyphAtIndex: (unsigned)glyphIndex
{ {
return NSZeroPoint; return NSZeroPoint;
@ -933,8 +958,8 @@ forStartOfGlyphRange: (NSRange)glyphRange
// Returns the range including the first glyph from glyphIndex on back // Returns the range including the first glyph from glyphIndex on back
// that has a location set and up to, but not including the next glyph // that has a location set and up to, but not including the next glyph
// that has a location set. This is a range of glyphs that can be shown // that has a location set. This is a range of glyphs that can be
// with a single postscript show operation. // shown with a single postscript show operation.
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex: (unsigned)glyphIndex - (NSRange) rangeOfNominallySpacedGlyphsContainingIndex: (unsigned)glyphIndex
{ {
GSLineLayoutInfo *theLine; GSLineLayoutInfo *theLine;
@ -949,22 +974,22 @@ forStartOfGlyphRange: (NSRange)glyphRange
return NSMakeRange(NSNotFound, 0); return NSMakeRange(NSNotFound, 0);
} }
// Returns an array of NSRects and the number of rects by reference which // Returns an array of NSRects and the number of rects by reference
// define the region in container that encloses the given range. If a // which define the region in container that encloses the given range.
// selected range is given in the second argument, the rectangles returned // If a selected range is given in the second argument, the rectangles
// will be correct for drawing the selection. Selection rectangles are // returned will be correct for drawing the selection. Selection
// generally more complicated than enclosing rectangles and supplying a // rectangles are generally more complicated than enclosing rectangles
// selected range is the clue these methods use to determine whether to // and supplying a selected range is the clue these methods use to
// go to the trouble of doing this special work. // determine whether to go to the trouble of doing this special work.
// If the caller is interested in this more from an enclosing point of // If the caller is interested in this more from an enclosing point of
// view rather than a selection point of view pass {NSNotFound, 0} as // view rather than a selection point of view pass {NSNotFound, 0} as
// the selected range. This method works hard to do the minimum amount // the selected range. This method works hard to do the minimum
// of work required to answer the question. The resulting array is owned // amount of work required to answer the question. The resulting
// by the layoutManager and will be reused when either of these two methods // array is owned by the layoutManager and will be reused when either
// OR -boundingRectForGlyphRange:inTextContainer: is called. Note that // of these two methods OR -boundingRectForGlyphRange:inTextContainer:
// one of these methods may be called indirectly. The upshot is that if // is called. Note that one of these methods may be called
// you aren't going to use the rects right away, you should copy them to // indirectly. The upshot is that if you aren't going to use the
// another location. // rects right away, you should copy them to another location.
- (NSRect*) rectArrayForCharacterRange: (NSRange)charRange - (NSRect*) rectArrayForCharacterRange: (NSRange)charRange
withinSelectedCharacterRange: (NSRange)selChareRange withinSelectedCharacterRange: (NSRange)selChareRange
inTextContainer: (NSTextContainer*)aTextContainer inTextContainer: (NSTextContainer*)aTextContainer
@ -1022,18 +1047,18 @@ forStartOfGlyphRange: (NSRange)glyphRange
// completely encloses the glyphs in the given glyphRange that are in // completely encloses the glyphs in the given glyphRange that are in
// the given container. If no container is given, then the container // the given container. If no container is given, then the container
// of the first glyph is assumed. Basically, the range is intersected // of the first glyph is assumed. Basically, the range is intersected
// with the container's range before computing the bounding rect. // with the container's range before computing the bounding rect.
// This method can be used to translate glyph ranges into display rectangles // This method can be used to translate glyph ranges into display
// for invalidation. // rectangles for invalidation.
- (NSRect) boundingRectForGlyphRange: (NSRange)glyphRange - (NSRect) boundingRectForGlyphRange: (NSRange)glyphRange
inTextContainer: (NSTextContainer*)aTextContainer inTextContainer: (NSTextContainer*)aTextContainer
{ {
/* Returns a single bounding rectangle enclosing all glyphs and other /* Returns a single bounding rectangle enclosing all glyphs and other
marks drawn in aTextContainer for glyphRange, including glyphs that draw marks drawn in aTextContainer for glyphRange, including glyphs that
outside their line fragment rectangles and text attributes such as draw outside their line fragment rectangles and text attributes such
underlining. This method is useful for determining the area that needs to as underlining. This method is useful for determining the area that
be redrawn when a range of glyphs changes. */ needs to be redrawn when a range of glyphs changes. */
/* /*
unsigned rectCount; unsigned rectCount;
NSRect *rects = [self rectArrayForCharacterRange: [self glyphRangeForTextContainer: aTextContainer] NSRect *rects = [self rectArrayForCharacterRange: [self glyphRangeForTextContainer: aTextContainer]
@ -1082,10 +1107,11 @@ be redrawn when a range of glyphs changes. */
// Returns the index of the glyph which under the given point which is // Returns the index of the glyph which under the given point which is
// expressed in the given container's coordinate system. If no glyph // expressed in the given container's coordinate system. If no glyph
// is under the point the "nearest" glyph is returned where "nearest" // is under the point the "nearest" glyph is returned where "nearest"
// is defined in such a way that selection works like it should. // is defined in such a way that selection works like it should. See
// See the implementation for details. partialFraction, if provided, // the implementation for details. partialFraction, if provided, is
// is set to the fraction of the distance between the location of the // set to the fraction of the distance between the location of the
// glyph returned and the location of the next glyph that the point is at. // glyph returned and the location of the next glyph that the point is
// at.
- (unsigned) glyphIndexForPoint: (NSPoint)aPoint - (unsigned) glyphIndexForPoint: (NSPoint)aPoint
inTextContainer: (NSTextContainer*)aTextContainer inTextContainer: (NSTextContainer*)aTextContainer
fractionOfDistanceThroughGlyph: (float*)partialFraction fractionOfDistanceThroughGlyph: (float*)partialFraction
@ -1111,15 +1137,16 @@ be redrawn when a range of glyphs changes. */
{ {
} }
// Some glyphs are not shown. This will cause glyph generation and layout as needed.. // Some glyphs are not shown. This will cause glyph generation and
// layout as needed..
- (BOOL) notShownAttributeForGlyphAtIndex: (unsigned)glyphIndex - (BOOL) notShownAttributeForGlyphAtIndex: (unsigned)glyphIndex
{ {
return YES; return YES;
} }
// If YES, and the rulebooks and fonts in use support it, whitespace and other // If YES, and the rulebooks and fonts in use support it, whitespace
// "invisible" unicodes will be shown with special glyphs (ie "." for space, // and other "invisible" unicodes will be shown with special glyphs
// the little CR icon for new lines, etc...) // (ie "." for space, the little CR icon for new lines, etc...)
- (void) setShowsInvisibleCharacters: (BOOL)flag - (void) setShowsInvisibleCharacters: (BOOL)flag
{ {
_showsInvisibleChars = flag; _showsInvisibleChars = flag;
@ -1130,9 +1157,10 @@ be redrawn when a range of glyphs changes. */
return _showsInvisibleChars; return _showsInvisibleChars;
} }
// If YES, and the rulebooks and fonts in use support it, control characters // If YES, and the rulebooks and fonts in use support it, control
// will be rendered visibly (usually like "^M", but possibly with special // characters will be rendered visibly (usually like "^M", but
// glyphs if the the font and rulebook supports it). // possibly with special glyphs if the the font and rulebook supports
// it).
- (void) setShowsControlCharacters: (BOOL)flag - (void) setShowsControlCharacters: (BOOL)flag
{ {
_showsControlChars = flag; _showsControlChars = flag;
@ -1160,7 +1188,8 @@ be redrawn when a range of glyphs changes. */
// Finding unlaid characters/glyphs // Finding unlaid characters/glyphs
// //
// Returns (by reference) the character index or glyph index or both // Returns (by reference) the character index or glyph index or both
// of the first unlaid character/glyph in the layout manager at this time. // of the first unlaid character/glyph in the layout manager at this
// time.
- (void) getFirstUnlaidCharacterIndex: (unsigned*)charIndex - (void) getFirstUnlaidCharacterIndex: (unsigned*)charIndex
glyphIndex: (unsigned*)glyphIndex glyphIndex: (unsigned*)glyphIndex
{ {
@ -1184,7 +1213,8 @@ be redrawn when a range of glyphs changes. */
// //
// Using screen fonts // Using screen fonts
// //
// Sets whether this layoutManager will use screen fonts when it is possible to do so. // Sets whether this layoutManager will use screen fonts when it is
// possible to do so.
- (void) setUsesScreenFonts: (BOOL)flag - (void) setUsesScreenFonts: (BOOL)flag
{ {
_usesScreenFonts = flag; _usesScreenFonts = flag;
@ -1195,14 +1225,15 @@ be redrawn when a range of glyphs changes. */
return _usesScreenFonts; return _usesScreenFonts;
} }
// Returns a font to use in place of originalFont. This method is used // Returns a font to use in place of originalFont. This method is
// to substitute screen fonts for regular fonts. If screen fonts are // used to substitute screen fonts for regular fonts. If screen fonts
// allowed AND no NSTextView managed by this layoutManager is scaled or // are allowed AND no NSTextView managed by this layoutManager is
// rotated AND a screen font is available for originalFont, it is returned, // scaled or rotated AND a screen font is available for originalFont,
// otherwise originalFont is returned. MF:??? This method will eventually // it is returned, otherwise originalFont is returned. MF:??? This
// need to know or be told whether use of screen fonts is appropriate in a // method will eventually need to know or be told whether use of
// given situation (ie screen font used might be enabled or disabled, we // screen fonts is appropriate in a given situation (ie screen font
// might be printing, etc...). This method causes no generation. // used might be enabled or disabled, we might be printing, etc...).
// This method causes no generation.
- (NSFont*) substituteFontForFont: (NSFont*)originalFont - (NSFont*) substituteFontForFont: (NSFont*)originalFont
{ {
NSFont *replaceFont; NSFont *replaceFont;
@ -1246,8 +1277,8 @@ be redrawn when a range of glyphs changes. */
// //
// Managing the responder chain // Managing the responder chain
// //
// Returns YES if the firstResponder of the given window is one of // Returns YES if the firstResponder of the given window is one of the
// the NSTextViews attached to this NSLayoutManager. // NSTextViews attached to this NSLayoutManager.
- (BOOL) layoutManagerOwnsFirstResponderInWindow: (NSWindow*)aWindow - (BOOL) layoutManagerOwnsFirstResponderInWindow: (NSWindow*)aWindow
{ {
return NO; return NO;
@ -1354,14 +1385,14 @@ aLine->lineFragmentRect.size.height);
// for the glyph range given. The second method potentailly breaks // for the glyph range given. The second method potentailly breaks
// the range it is given up into subranges and calls drawUnderline... // the range it is given up into subranges and calls drawUnderline...
// for ranges that should actually have the underline drawn. As // for ranges that should actually have the underline drawn. As
// examples of why there are two methods, consider two situations. // examples of why there are two methods, consider two situations.
// First, in all cases you don't want to underline the leading and // First, in all cases you don't want to underline the leading and
// trailing whitespace on a line. The -underlineGlyphRange... method // trailing whitespace on a line. The -underlineGlyphRange... method
// is passed glyph ranges that have underlining turned on, but it will // is passed glyph ranges that have underlining turned on, but it will
// then look for this leading and trailing white space and only pass // then look for this leading and trailing white space and only pass
// the ranges that should actually be underlined to -drawUnderline... // the ranges that should actually be underlined to -drawUnderline...
// Second, if the underlineType: indicates that only words, (ie no // Second, if the underlineType: indicates that only words, (ie no
// whitespace), should be underlined, then -underlineGlyphRange... // whitespace), should be underlined, then -underlineGlyphRange...
// will carve the range it is passed up into words and only pass word // will carve the range it is passed up into words and only pass word
// ranges to -drawUnderline. // ranges to -drawUnderline.
- (void) underlineGlyphRange: (NSRange)glyphRange - (void) underlineGlyphRange: (NSRange)glyphRange
@ -1388,24 +1419,23 @@ aLine->lineFragmentRect.size.height);
@end /* NSLayoutManager */ @end /* NSLayoutManager */
/* The methods laid out here are not correct, however the code they /* The methods laid out here are not correct, however the code they
contain for the most part is. Therefore, my country and a handsome gift of contain for the most part is. Therefore, my country and a handsome
Ghiradelli chocolate to he who puts all the pieces together : ) */ gift of Ghiradelli chocolate to he who puts all the pieces together :) */
/* /*
* A little utility function to determine the range of characters in a scanner * A little utility function to determine the range of characters in a
* that are present in a specified character set. * scanner that are present in a specified character set. */
*/
static inline NSRange static inline NSRange
scanRange(NSScanner *scanner, NSCharacterSet* aSet) scanRange (NSScanner *scanner, NSCharacterSet* aSet)
{ {
unsigned start = [scanner scanLocation]; unsigned start = [scanner scanLocation];
unsigned end = start; unsigned end = start;
if ([scanner scanCharactersFromSet: aSet intoString: 0] == YES) if ([scanner scanCharactersFromSet: aSet intoString: 0] == YES)
{ {
end = [scanner scanLocation]; end = [scanner scanLocation];
} }
return NSMakeRange(start, end - start); return NSMakeRange (start, end - start);
} }
@implementation NSLayoutManager (Private) @implementation NSLayoutManager (Private)