1 |
/* |
2 |
GSLayoutManager.h |
3 |
|
4 |
Copyright (C) 2002, 2003 Free Software Foundation, Inc. |
5 |
|
6 |
Author: Alexander Malmberg <alexander@malmberg.org> |
7 |
Date: November 2002 - February 2003 |
8 |
|
9 |
This file is part of the GNUstep GUI Library. |
10 |
|
11 |
This library is free software; you can redistribute it and/or |
12 |
modify it under the terms of the GNU Library General Public |
13 |
License as published by the Free Software Foundation; either |
14 |
version 2 of the License, or (at your option) any later version. |
15 |
|
16 |
This library is distributed in the hope that it will be useful, |
17 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
19 |
Library General Public License for more details. |
20 |
|
21 |
You should have received a copy of the GNU Library General Public |
22 |
License along with this library; see the file COPYING.LIB. |
23 |
If not, write to the Free Software Foundation, |
24 |
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
25 |
*/ |
26 |
|
27 |
#ifndef _GNUstep_H_GSLayoutManager |
28 |
#define _GNUstep_H_GSLayoutManager |
29 |
|
30 |
#include <Foundation/NSObject.h> |
31 |
#include <Foundation/NSGeometry.h> |
32 |
#include <AppKit/NSFont.h> |
33 |
|
34 |
@class GSTypesetter; |
35 |
@class NSTextStorage,NSTextContainer; |
36 |
|
37 |
typedef enum |
38 |
{ |
39 |
NSGlyphInscribeBase = 0, |
40 |
NSGlyphInscribeBelow = 1, |
41 |
NSGlyphInscribeAbove = 2, |
42 |
NSGlyphInscribeOverstrike = 3, |
43 |
NSGlyphInscribeOverBelow = 4 |
44 |
} NSGlyphInscription; |
45 |
|
46 |
@interface GSLayoutManager : NSObject |
47 |
{ |
48 |
@protected |
49 |
NSTextStorage *_textStorage; |
50 |
|
51 |
id _delegate; |
52 |
|
53 |
BOOL usesScreenFonts; |
54 |
BOOL backgroundLayoutEnabled; |
55 |
BOOL showsInvisibleCharacters; |
56 |
BOOL showsControlCharacters; |
57 |
|
58 |
GSTypesetter *typesetter; |
59 |
|
60 |
|
61 |
/* Glyph storage */ |
62 |
|
63 |
/* Skip list of runs */ |
64 |
struct GSLayoutManager_glyph_run_head_s *glyphs; |
65 |
|
66 |
/* number of runs created from existing text (ie. not as a result of |
67 |
stuff being invalidated) */ |
68 |
int glyph_num_end_runs; |
69 |
|
70 |
|
71 |
/* Layout storage */ |
72 |
/* OPT: This is just a simple implementation that should let me figure out |
73 |
how it's supposed to work. It's functional and correct, but it isn't fast. */ |
74 |
|
75 |
unsigned int layout_glyph, layout_char; |
76 |
|
77 |
struct GSLayoutManager_textcontainer_s *textcontainers; |
78 |
int num_textcontainers; |
79 |
|
80 |
NSRect extra_rect, extra_used_rect; |
81 |
NSTextContainer *extra_textcontainer; |
82 |
|
83 |
|
84 |
/* For -rectArrayForGlyphRange:... */ |
85 |
NSRect *rect_array; |
86 |
int rect_array_size; |
87 |
|
88 |
|
89 |
/* |
90 |
Cached run. GSHorizontalTypesetter (and other typesetters, presumably) |
91 |
often walk linearly through the glyphs. Thus, for many methods, we cache |
92 |
the last run so we can quickly get more information for the next glyph. |
93 |
*/ |
94 |
struct GSLayoutManager_glyph_run_s *cached_run; |
95 |
unsigned int cached_pos, cached_cpos; |
96 |
} |
97 |
|
98 |
|
99 |
- (NSTextStorage *) textStorage; |
100 |
- (void) setTextStorage: (NSTextStorage *)aTextStorage; |
101 |
- (void) replaceTextStorage: (NSTextStorage *)newTextStorage; |
102 |
|
103 |
|
104 |
- (id) delegate; |
105 |
- (void) setDelegate: (id)aDelegate; |
106 |
|
107 |
|
108 |
-(GSTypesetter *) typesetter; |
109 |
-(void) setTypesetter: (GSTypesetter *)typesetter; |
110 |
|
111 |
|
112 |
- (void) setBackgroundLayoutEnabled: (BOOL)flag; |
113 |
- (BOOL) backgroundLayoutEnabled; |
114 |
|
115 |
- (void) setShowsInvisibleCharacters: (BOOL)flag; |
116 |
- (BOOL) showsInvisibleCharacters; |
117 |
|
118 |
- (void) setShowsControlCharacters: (BOOL)flag; |
119 |
- (BOOL) showsControlCharacters; |
120 |
|
121 |
|
122 |
/** Font handling **/ |
123 |
|
124 |
- (BOOL) usesScreenFonts; |
125 |
- (void) setUsesScreenFonts: (BOOL)flag; |
126 |
|
127 |
- (NSFont *) substituteFontForFont: (NSFont *)originalFont; |
128 |
|
129 |
|
130 |
/* |
131 |
(?) |
132 |
Sent by the NSTextStorage. mask tells us if attributes or characters (or |
133 |
both) have been changed. range is the range of directly modified |
134 |
characters. invalidatedRange is the range of characters affected by the |
135 |
changes (contains range but may be larger due to eg. attribute fixing). |
136 |
If characters have been edited, lengthChange has the text length delta. |
137 |
*/ |
138 |
- (void) textStorage: (NSTextStorage *)aTextStorage |
139 |
edited: (unsigned int)mask |
140 |
range: (NSRange)range |
141 |
changeInLength: (int)lengthChange |
142 |
invalidatedRange: (NSRange)invalidatedRange; |
143 |
|
144 |
@end |
145 |
|
146 |
|
147 |
@interface GSLayoutManager (glyphs) |
148 |
|
149 |
/** Glyph handling **/ |
150 |
|
151 |
/* |
152 |
Mark the glyphs for the characters in aRange as invalid. lengthChange |
153 |
is the text length delta. If not NULL, the range of characters actually |
154 |
affected (_after_ the change) will be returned in actualRange. |
155 |
|
156 |
This method is used internally and should _not_ be called. (It interacts |
157 |
in complex ways with layout invalidation.) |
158 |
*/ |
159 |
- (void) invalidateGlyphsForCharacterRange: (NSRange)aRange |
160 |
changeInLength: (int)lengthChange |
161 |
actualCharacterRange: (NSRange *)actualRange; |
162 |
|
163 |
/* |
164 |
These are internal methods and should _not_ be called. |
165 |
*/ |
166 |
- (void) insertGlyph: (NSGlyph)aGlyph |
167 |
atGlyphIndex: (unsigned int)glyphIndex |
168 |
characterIndex: (unsigned int)charIndex; |
169 |
- (void) replaceGlyphAtIndex: (unsigned int)glyphIndex |
170 |
withGlyph: (NSGlyph)newGlyph; |
171 |
- (void) deleteGlyphsInRange: (NSRange)aRange; |
172 |
- (void) setCharacterIndex: (unsigned int)charIndex |
173 |
forGlyphAtIndex: (unsigned int)glyphIndex; |
174 |
|
175 |
|
176 |
/* Returns total number of glyphs. */ |
177 |
- (unsigned int) numberOfGlyphs; |
178 |
|
179 |
/* Returns the glyph at glyphIndex or raises an NSRangeException if the |
180 |
index is invalid (past the end of the glyphs). */ |
181 |
- (NSGlyph) glyphAtIndex: (unsigned int)glyphIndex; |
182 |
|
183 |
/* Returns the glyph at glyphIndex and sets isValidIndex to YES if the index |
184 |
is valid. Otherwise, the return value is arbitrary and isValidIndex is set |
185 |
to NO. */ |
186 |
- (NSGlyph) glyphAtIndex: (unsigned int)glyphIndex |
187 |
isValidIndex: (BOOL *)isValidIndex; |
188 |
|
189 |
/* Returns if the glyph at glyphIndex is valid or not */ |
190 |
- (BOOL) isValidGlyphIndex: (unsigned int)glyphIndex; |
191 |
|
192 |
/* Copies displayed glyphs to glyphArray for glyphRange. Returns the number |
193 |
of glyphs actually copied to the array. NSRangeException of the range is |
194 |
invalid (extends beyond the end of glyphs). */ |
195 |
- (unsigned int) getGlyphs: (NSGlyph *)glyphArray |
196 |
range: (NSRange)glyphRange; |
197 |
|
198 |
/* Return the first character for the glyph at glyphIndex. |
199 |
(NSRangeException?) */ |
200 |
- (unsigned int) characterIndexForGlyphAtIndex: (unsigned int)glyphIndex; |
201 |
|
202 |
/* Returns the range of glyphs for the characters in charRange. If |
203 |
actualRange isn't NULL, the exact range of characters for the glyphs in the |
204 |
returned range is returned there. */ |
205 |
- (NSRange) glyphRangeForCharacterRange: (NSRange)charRange |
206 |
actualCharacterRange: (NSRange *)actualCharRange; |
207 |
|
208 |
/* Returns the range of characters for the glyphs in glyphRange. Returns |
209 |
the actual glyphs for the characters in the range in actualGlyphRange, if |
210 |
it isn't NULL. */ |
211 |
- (NSRange) characterRangeForGlyphRange: (NSRange)glyphRange |
212 |
actualGlyphRange: (NSRange *)actualGlyphRange; |
213 |
|
214 |
|
215 |
/* These can be used to set arbitrary tags on individual glyphs. |
216 |
Non-negative tags are reserved. You must provide storage yourself (by |
217 |
subclassing). */ |
218 |
- (void) setIntAttribute: (int)attributeTag |
219 |
value: (int)anInt |
220 |
forGlyphAtIndex: (unsigned int)glyphIndex; |
221 |
- (int) intAttribute: (int)attributeTag |
222 |
forGlyphAtIndex: (unsigned int)glyphIndex; |
223 |
|
224 |
|
225 |
/* Returns the font actually used for a range of glyphs. This isn't |
226 |
necessarily the font specified by NSFontAttributeName; both the typesetter |
227 |
and the layout manager can substitute a different font (the typesetter might |
228 |
eg. substitute a smaller font for sub-/super-scripted text, and the layout |
229 |
manager might be substituting screen fonts. */ |
230 |
- (NSFont *) effectiveFontForGlyphAtIndex: (unsigned int)glyphIndex |
231 |
range: (NSRange *)range; /* GNUstep extension */ |
232 |
|
233 |
|
234 |
- (void) setDrawsOutsideLineFragment: (BOOL)flag |
235 |
forGlyphAtIndex: (unsigned int)glyphIndex; |
236 |
- (BOOL) drawsOutsideLineFragmentForGlyphAtIndex: (unsigned int) glyphIndex; |
237 |
|
238 |
- (void) setNotShownAttribute: (BOOL)flag |
239 |
forGlyphAtIndex: (unsigned int)glyphIndex; |
240 |
- (BOOL) notShownAttributeForGlyphAtIndex: (unsigned int) glyphIndex; |
241 |
|
242 |
@end |
243 |
|
244 |
|
245 |
@interface GSLayoutManager (layout) |
246 |
|
247 |
/** Text containers **/ |
248 |
|
249 |
- (NSArray *) textContainers; |
250 |
|
251 |
- (void) addTextContainer: (NSTextContainer *)container; |
252 |
- (void) insertTextContainer: (NSTextContainer*)aTextContainer |
253 |
atIndex: (unsigned int)index; |
254 |
- (void) removeTextContainerAtIndex: (unsigned int)index; |
255 |
|
256 |
- (void) textContainerChangedGeometry: (NSTextContainer *)aContainer; |
257 |
|
258 |
|
259 |
/** Layout **/ |
260 |
|
261 |
/* |
262 |
This method is used internally and should _not_ be called. (It interacts |
263 |
in complex ways with glyph invalidation, and with itself when doing soft |
264 |
invalidation.) |
265 |
*/ |
266 |
- (void) invalidateLayoutForCharacterRange: (NSRange)aRange |
267 |
isSoft: (BOOL)flag |
268 |
actualCharacterRange: (NSRange *)actualRange; |
269 |
|
270 |
|
271 |
- (void) setTextContainer: (NSTextContainer *)aTextContainer |
272 |
forGlyphRange: (NSRange)glyphRange; |
273 |
|
274 |
- (void) setLineFragmentRect: (NSRect)fragmentRect |
275 |
forGlyphRange: (NSRange)glyphRange |
276 |
usedRect: (NSRect)usedRect; |
277 |
|
278 |
- (void) setLocation: (NSPoint)location |
279 |
forStartOfGlyphRange: (NSRange)glyphRange; |
280 |
|
281 |
- (void) setAttachmentSize: (NSSize)attachmentSize |
282 |
forGlyphRange: (NSRange)glyphRange; /* not OPENSTEP */ |
283 |
|
284 |
|
285 |
- (NSTextContainer *) textContainerForGlyphAtIndex: (unsigned int)glyphIndex |
286 |
effectiveRange: (NSRange *)effectiveRange; |
287 |
- (NSRect) lineFragmentRectForGlyphAtIndex: (unsigned int)glyphIndex |
288 |
effectiveRange: (NSRange *)effectiveGlyphRange; |
289 |
- (NSRect) lineFragmentUsedRectForGlyphAtIndex: (unsigned int)glyphIndex |
290 |
effectiveRange: (NSRange *)effectiveGlyphRange; |
291 |
|
292 |
|
293 |
/* |
294 |
The typesetter may set this to mark where the rectangle the insertion point |
295 |
is to be placed if the insertion point is beyond the last character of the |
296 |
text. The extra text container is reset to nil any time layout is |
297 |
invalidated. |
298 |
*/ |
299 |
-(void) setExtraLineFragmentRect: (NSRect)linefrag |
300 |
usedRect: (NSRect)used |
301 |
textContainer: (NSTextContainer *)tc; |
302 |
|
303 |
-(NSRect) extraLineFragmentRect; |
304 |
-(NSRect) extraLineFragmentUsedRect; |
305 |
-(NSTextContainer *) extraLineFragmentTextContainer; |
306 |
|
307 |
|
308 |
/* Extension, but without this, there's no way to get the starting locations |
309 |
of the nominally spaced glyphs. */ |
310 |
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex:(unsigned int)glyphIndex |
311 |
startLocation: (NSPoint *)p; |
312 |
|
313 |
- (NSRange) rangeOfNominallySpacedGlyphsContainingIndex:(unsigned int)glyphIndex; |
314 |
|
315 |
/* The union of all line frag rects' used rects. (TODO: shouldn't this be |
316 |
just the union of all the line frag rects?) */ |
317 |
- (NSRect) usedRectForTextContainer: (NSTextContainer *)container; |
318 |
|
319 |
- (NSRange) glyphRangeForTextContainer: (NSTextContainer *)container; |
320 |
|
321 |
|
322 |
- (unsigned int) firstUnlaidCharacterIndex; |
323 |
- (unsigned int) firstUnlaidGlyphIndex; |
324 |
- (void) getFirstUnlaidCharacterIndex: (unsigned int *)charIndex |
325 |
glyphIndex: (unsigned int *)glyphIndex; |
326 |
|
327 |
|
328 |
/* |
329 |
Basic (and experimental) methods that let the typesetter use soft-invalidated |
330 |
layout information. |
331 |
*/ |
332 |
-(void) _softInvalidateUseLineFrags: (int)num |
333 |
withShift: (NSSize)shift |
334 |
inTextContainer: (NSTextContainer *)textContainer; |
335 |
-(NSRect) _softInvalidateLineFragRect: (int)index |
336 |
firstGlyph: (unsigned int *)first_glyph |
337 |
nextGlyph: (unsigned int *)next_glyph |
338 |
inTextContainer: (NSTextContainer *)textContainer; |
339 |
-(unsigned int) _softInvalidateFirstGlyphInTextContainer: (NSTextContainer *)textContainer; |
340 |
-(unsigned int) _softInvalidateNumberOfLineFragsInTextContainer: (NSTextContainer *)textContainer; |
341 |
|
342 |
@end |
343 |
|
344 |
|
345 |
@interface NSObject (GSLayoutManagerDelegate) |
346 |
-(void) layoutManager: (GSLayoutManager *)layoutManager |
347 |
didCompleteLayoutForTextContainer: (NSTextContainer *)textContainer |
348 |
atEnd: (BOOL)atEnd; |
349 |
@end |
350 |
|
351 |
|
352 |
#endif |
353 |
|