]> git.saurik.com Git - apple/icu.git/blob - icuSources/layoutex/layout/ParagraphLayout.h
ICU-6.2.22.tar.gz
[apple/icu.git] / icuSources / layoutex / layout / ParagraphLayout.h
1 /*
2 **********************************************************************
3 * Copyright (C) 2002-2004, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 */
7
8 #ifndef __PARAGRAPHLAYOUT_H
9
10 #define __PARAGRAPHLAYOUT_H
11
12 /*
13 * ParagraphLayout doesn't make much sense without
14 * BreakIterator...
15 */
16 #include "unicode/uscript.h"
17 #if ! UCONFIG_NO_BREAK_ITERATION
18
19 #include "layout/LETypes.h"
20 #include "layout/LEFontInstance.h"
21 #include "layout/LayoutEngine.h"
22 #include "unicode/ubidi.h"
23 #include "unicode/brkiter.h"
24
25 #include "layout/RunArrays.h"
26
27 U_NAMESPACE_BEGIN
28
29 /**
30 * ParagraphLayout.
31 *
32 * The <code>ParagraphLayout</code> object will analyze the text into runs of text in the
33 * same font, script and direction, and will create a <code>LayoutEngine</code> object for each run.
34 * The <code>LayoutEngine</code> will transform the characters into glyph codes in visual order.
35 *
36 * Clients can use this to break a paragraph into lines, and to display the glyphs in each line.
37 *
38 */
39 class U_LAYOUTEX_API ParagraphLayout : public UObject
40 {
41 public:
42 class VisualRun;
43
44 /**
45 * This class represents a single line of text in a <code>ParagraphLayout</code>. They
46 * can only be created by calling <code>ParagraphLayout::nextLine()</code>. Each line
47 * consists of multiple visual runs, represented by <code>ParagraphLayout::VisualRun</code>
48 * objects.
49 *
50 * @see ParagraphLayout
51 * @see ParagraphLayout::VisualRun
52 *
53 * @draft ICU 2.6
54 */
55 class U_LAYOUTEX_API Line : public UObject
56 {
57 public:
58 /**
59 * The constructor is private since these objects can only be
60 * created by <code>ParagraphLayout</code>. However, it is the
61 * clients responsibility to destroy the objects, so the destructor
62 * is public.
63 *
64 * @draft ICU 2.6
65 */
66 ~Line();
67
68 /**
69 * Count the number of visual runs in the line.
70 *
71 * @return the number of visual runs.
72 *
73 * @draft ICU 2.6
74 */
75 le_int32 countRuns() const;
76
77 /**
78 * Get the ascent of the line. This is the maximum ascent
79 * of all the fonts on the line.
80 *
81 * @return the ascent of the line.
82 *
83 * @draft ICU 2.6
84 */
85 le_int32 getAscent() const;
86
87 /**
88 * Get the descent of the line. This is the maximum descent
89 * of all the fonts on the line.
90 *
91 * @return the descent of the line.
92 *
93 * @draft ICU 2.6
94 */
95 le_int32 getDescent() const;
96
97 /**
98 * Get the leading of the line. This is the maximum leading
99 * of all the fonts on the line.
100 *
101 * @return the leading of the line.
102 *
103 * @draft ICU 2.6
104 */
105 le_int32 getLeading() const;
106
107 /**
108 * Get the width of the line. This is a convenience method
109 * which returns the last X position of the last visual run
110 * in the line.
111 *
112 * @return the width of the line.
113 *
114 * @draft ICU 2.8
115 */
116 le_int32 getWidth() const;
117
118 /**
119 * Get a <code>ParagraphLayout::VisualRun</code> object for a given
120 * visual run in the line.
121 *
122 * @param runIndex is the index of the run, in visual order.
123 *
124 * @return the <code>ParagraphLayout::VisualRun</code> object representing the
125 * visual run. This object is owned by the <code>Line</code> object which
126 * created it, and will remain valid for as long as the <code>Line</code>
127 * object is valid.
128 *
129 * @see ParagraphLayout::VisualRun
130 *
131 * @draft ICU 2.6
132 */
133 const VisualRun *getVisualRun(le_int32 runIndex) const;
134
135 /**
136 * ICU "poor man's RTTI", returns a UClassID for the actual class.
137 *
138 * @draft ICU 2.6
139 */
140 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
141
142 /**
143 * ICU "poor man's RTTI", returns a UClassID for this class.
144 *
145 * @draft ICU 2.6
146 */
147 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
148
149 private:
150
151 /**
152 * The address of this static class variable serves as this class's ID
153 * for ICU "poor man's RTTI".
154 */
155 static const char fgClassID;
156
157 friend class ParagraphLayout;
158
159 le_int32 fAscent;
160 le_int32 fDescent;
161 le_int32 fLeading;
162
163 le_int32 fRunCount;
164 le_int32 fRunCapacity;
165
166 VisualRun **fRuns;
167
168 Line();
169 Line(const Line &other);
170 Line &operator=(const Line & /*other*/) { return *this; };
171
172 void computeMetrics();
173
174 void append(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
175 const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]);
176 };
177
178 /**
179 * This object represents a single visual run in a line of text in
180 * a paragraph. A visual run is text which is in the same font,
181 * script, and direction. The text is represented by an array of
182 * <code>LEGlyphIDs</code>, an array of (x, y) glyph positions and
183 * a table which maps indices into the glyph array to indices into
184 * the original character array which was used to create the paragraph.
185 *
186 * These objects are only created by <code>ParagraphLayout::Line</code> objects,
187 * so their constructors and destructors are private.
188 *
189 * @see ParagraphLayout::Line
190 *
191 * @draft ICU 2.6
192 */
193 class U_LAYOUTEX_API VisualRun : public UObject
194 {
195 public:
196 /**
197 * Get the <code>LEFontInstance</code> object which
198 * represents the font of the visual run. This will always
199 * be a non-composite font.
200 *
201 * @return the <code>LEFontInstance</code> object which represents the
202 * font of the visual run.
203 *
204 * @see LEFontInstance
205 *
206 * @draft ICU 2.6
207 */
208 const LEFontInstance *getFont() const;
209
210 /**
211 * Get the direction of the visual run.
212 *
213 * @return the direction of the run. This will be UBIDI_LTR if the
214 * run is left-to-right and UBIDI_RTL if the line is right-to-left.
215 *
216 * @draft ICU 2.6
217 */
218 UBiDiDirection getDirection() const;
219
220 /**
221 * Get the number of glyphs in the visual run.
222 *
223 * @return the number of glyphs.
224 *
225 * @draft ICU 2.6
226 */
227 le_int32 getGlyphCount() const;
228
229 /**
230 * Get the glyphs in the visual run. Glyphs with the values <code>0xFFFE</code> and
231 * <code>0xFFFF</code> should be ignored.
232 *
233 * @return the address of the array of glyphs for this visual run. The storage
234 * is owned by the <code>VisualRun</code> object and must not be deleted.
235 * It will remain valid as long as the <code>VisualRun</code> object is valid.
236 *
237 * @draft ICU 2.6
238 */
239 const LEGlyphID *getGlyphs() const;
240
241 /**
242 * Get the (x, y) positions of the glyphs in the visual run. To simplify storage
243 * management, the x and y positions are stored in a single array with the x positions
244 * at even offsets in the array and the corresponding y position in the following odd offset.
245 * There is an extra (x, y) pair at the end of the array which represents the advance of
246 * the final glyph in the run.
247 *
248 * @return the address of the array of glyph positions for this visual run. The storage
249 * is owned by the <code>VisualRun</code> object and must not be deleted.
250 * It will remain valid as long as the <code>VisualRun</code> object is valid.
251 *
252 * @draft ICU 2.6
253 */
254 const float *getPositions() const;
255
256 /**
257 * Get the glyph-to-character map for this visual run. This maps the indices into
258 * the glyph array to indices into the character array used to create the paragraph.
259 *
260 * @return the address of the character-to-glyph map for this visual run. The storage
261 * is owned by the <code>VisualRun</code> object and must not be deleted.
262 * It will remain valid as long as the <code>VisualRun</code> object is valid.
263 *
264 * @draft ICU 2.6
265 */
266 const le_int32 *getGlyphToCharMap() const;
267
268 /**
269 * A convenience method which returns the ascent value for the font
270 * associated with this run.
271 *
272 * @return the ascent value of this run's font.
273 *
274 * @draft ICU 2.6
275 */
276 le_int32 getAscent() const;
277
278 /**
279 * A convenience method which returns the descent value for the font
280 * associated with this run.
281 *
282 * @return the descent value of this run's font.
283 *
284 * @draft ICU 2.6
285 */
286 le_int32 getDescent() const;
287
288 /**
289 * A convenience method which returns the leading value for the font
290 * associated with this run.
291 *
292 * @return the leading value of this run's font.
293 *
294 * @draft ICU 2.6
295 */
296 le_int32 getLeading() const;
297
298 /**
299 * ICU "poor man's RTTI", returns a UClassID for the actual class.
300 *
301 * @draft ICU 2.6
302 */
303 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
304
305 /**
306 * ICU "poor man's RTTI", returns a UClassID for this class.
307 *
308 * @draft ICU 2.6
309 */
310 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
311
312 private:
313
314 /**
315 * The address of this static class variable serves as this class's ID
316 * for ICU "poor man's RTTI".
317 */
318 static const char fgClassID;
319
320 const LEFontInstance *fFont;
321 const UBiDiDirection fDirection;
322
323 const le_int32 fGlyphCount;
324
325 const LEGlyphID *fGlyphs;
326 const float *fPositions;
327 const le_int32 *fGlyphToCharMap;
328
329 friend class Line;
330
331 VisualRun();
332 VisualRun(const VisualRun &other);
333 VisualRun &operator=(const VisualRun &other) { return *this; };
334
335 VisualRun(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
336 const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]);
337
338 ~VisualRun();
339 };
340
341 /**
342 * Construct a <code>ParagraphLayout</code> object for a styled paragraph. The paragraph is specified
343 * as runs of text all in the same font. An <code>LEFontInstance</code> object and a limit offset
344 * are specified for each font run. The limit offset is the offset of the character immediately
345 * after the font run.
346 *
347 * Clients can optionally specify directional runs and / or script runs. If these aren't specified
348 * they will be computed.
349 *
350 * If any errors are encountered during construction, <code>status</code> will be set, and the object
351 * will be set to be empty.
352 *
353 * @param chars is an array of the characters in the paragraph
354 *
355 * @param count is the number of characters in the paragraph.
356 *
357 * @param fontRuns a pointer to a <code>FontRuns</code> object representing the font runs.
358 *
359 * @param levelRuns is a pointer to a <code>ValueRuns</code> object representing the directional levels.
360 * If this pointer in <code>NULL</code> the levels will be determined by running the Unicde
361 * Bidi algorithm.
362 *
363 * @param scriptRuns is a pointer to a <code>ValueRuns</code> object representing script runs.
364 * If this pointer in <code>NULL</code> the script runs will be determined using the
365 * Unicode code points.
366 *
367 * @param localeRuns is a pointer to a <code>LocaleRuns</code> object representing locale runs.
368 * The <code>Locale</code> objects are used to determind the language of the text. If this
369 * pointer is <code>NULL</code> the default locale will be used for all of the text.
370 *
371 * @param paragraphLevel is the directionality of the paragraph, as in the UBiDi object.
372 *
373 * @param vertical is <code>TRUE</code> if the paragraph should be set vertically.
374 *
375 * @param status will be set to any error code encountered during construction.
376 *
377 * @see ubidi.h
378 * @see LEFontInstance.h
379 * @see LayoutEngine.h
380 * @see RunArrays.h
381 *
382 * @draft ICU 2.8
383 */
384 ParagraphLayout(const LEUnicode chars[], le_int32 count,
385 const FontRuns *fontRuns,
386 const ValueRuns *levelRuns,
387 const ValueRuns *scriptRuns,
388 const LocaleRuns *localeRuns,
389 UBiDiLevel paragraphLevel, le_bool vertical,
390 LEErrorCode &status);
391
392 /**
393 * The destructor. Virtual so that it works correctly with
394 * sublcasses.
395 *
396 * @draft ICU 2.6
397 */
398 ~ParagraphLayout();
399
400 // Note: the following is #if 0'd out because there's no good
401 // way to implement it without either calling layoutEngineFactory()
402 // or duplicating the logic there...
403 #if 0
404 /**
405 * Examine the given styled paragraph and determine if it contains any text which
406 * requires complex processing. (i.e. that cannot be correctly rendered by
407 * just mapping the characters to glyphs and rendering them in order)
408 *
409 * @param chars is an array of the characters in the paragraph
410 *
411 * @param count is the number of characters in the paragraph.
412 *
413 * @param fontRuns is a pointer to a <code>FontRuns</code> object representing the font runs.
414 *
415 * @return <code>TRUE</code> if the paragraph contains complex text.
416 *
417 * @draft ICU 2.6
418 */
419 static le_bool isComplex(const LEUnicode chars[], le_int32 count, const FontRuns *fontRuns);
420 #else
421 /**
422 * Examine the given text and determine if it contains characters in any
423 * script which requires complex processing to be rendered correctly.
424 *
425 * @param chars is an array of the characters in the paragraph
426 *
427 * @param count is the number of characters in the paragraph.
428 *
429 * @return <code>TRUE</code> if any of the text requires complex processing.
430 *
431 * @draft ICU 2.6
432 */
433 static le_bool isComplex(const LEUnicode chars[], le_int32 count);
434
435 #endif
436
437 /**
438 * Return the resolved paragraph level. This is useful for those cases
439 * where the bidi analysis has determined the level based on the first
440 * strong character in the paragraph.
441 *
442 * @return the resolved paragraph level.
443 *
444 * @draft ICU 2.6
445 */
446 UBiDiLevel getParagraphLevel();
447
448 /**
449 * Return the directionality of the text in the paragraph.
450 *
451 * @return <code>UBIDI_LTR</code> if the text is all left to right,
452 * <code>UBIDI_RTL</code> if the text is all right to left,
453 * or <code>UBIDI_MIXED</code> if the text has mixed direction.
454 *
455 * @draft ICU 2.6
456 */
457 UBiDiDirection getTextDirection();
458
459 /**
460 * Return the max ascent value for all the fonts
461 * in the paragraph.
462 *
463 * @return the ascent value.
464 *
465 * @draft ICU 2.6
466 */
467 virtual le_int32 getAscent() const;
468
469 /**
470 * Return the max descent value for all the fonts
471 * in the paragraph.
472 *
473 * @return the decent value.
474 *
475 * @draft ICU 2.6
476 */
477 virtual le_int32 getDescent() const;
478
479 /**
480 * Return the max leading value for all the fonts
481 * in the paragraph.
482 *
483 * @return the leading value.
484 *
485 * @draft ICU 2.6
486 */
487 virtual le_int32 getLeading() const;
488
489 /**
490 * Reset line breaking to start from the beginning of the paragraph.
491 *
492 *
493 * @draft ICU 2.6
494 */
495 void reflow();
496
497 /**
498 * Return a <code>ParagraphLayout::Line</code> object which represents next line
499 * in the paragraph. The width of the line is specified each time so that it can
500 * be varied to support arbitrary paragraph shapes.
501 *
502 * @param width is the width of the line. If <code>width</code> is less than or equal
503 * to zero, a <code>ParagraphLayout::Line</code> object representing the
504 * rest of the paragraph will be returned.
505 *
506 * @return a <code>ParagraphLayout::Line</code> object which represents the line. The caller
507 * is responsible for deleting the object. Returns <code>NULL</code> if there are no
508 * more lines in the paragraph.
509 *
510 * @see ParagraphLayout::Line
511 *
512 * @draft ICU 2.6
513 */
514 Line *nextLine(float width);
515
516 /**
517 * ICU "poor man's RTTI", returns a UClassID for the actual class.
518 *
519 * @draft ICU 2.6
520 */
521 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
522
523 /**
524 * ICU "poor man's RTTI", returns a UClassID for this class.
525 *
526 * @draft ICU 2.6
527 */
528 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
529
530 private:
531
532
533 /**
534 * The address of this static class variable serves as this class's ID
535 * for ICU "poor man's RTTI".
536 */
537 static const char fgClassID;
538
539 struct StyleRunInfo
540 {
541 LayoutEngine *engine;
542 const LEFontInstance *font;
543 const Locale *locale;
544 LEGlyphID *glyphs;
545 float *positions;
546 UScriptCode script;
547 UBiDiLevel level;
548 le_int32 runBase;
549 le_int32 runLimit;
550 le_int32 glyphBase;
551 le_int32 glyphCount;
552 };
553
554 ParagraphLayout() {};
555 ParagraphLayout(const ParagraphLayout & /*other*/) : UObject( ){};
556 ParagraphLayout &operator=(const ParagraphLayout & /*other*/) { return *this; };
557
558 void computeLevels(UBiDiLevel paragraphLevel);
559
560 Line *computeVisualRuns();
561 void appendRun(Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar);
562
563 void computeScripts();
564
565 void computeLocales();
566
567 void computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status);
568
569 void computeMetrics();
570
571 le_int32 getLanguageCode(const Locale *locale);
572
573 le_int32 getCharRun(le_int32 charIndex);
574
575 static le_bool isComplex(UScriptCode script);
576
577 le_int32 previousBreak(le_int32 charIndex);
578
579
580 const LEUnicode *fChars;
581 le_int32 fCharCount;
582
583 const FontRuns *fFontRuns;
584 const ValueRuns *fLevelRuns;
585 const ValueRuns *fScriptRuns;
586 const LocaleRuns *fLocaleRuns;
587
588 le_bool fVertical;
589 le_bool fClientLevels;
590 le_bool fClientScripts;
591 le_bool fClientLocales;
592
593 UBiDiLevel *fEmbeddingLevels;
594
595 le_int32 fAscent;
596 le_int32 fDescent;
597 le_int32 fLeading;
598
599 le_int32 *fGlyphToCharMap;
600 le_int32 *fCharToMinGlyphMap;
601 le_int32 *fCharToMaxGlyphMap;
602 float *fGlyphWidths;
603 le_int32 fGlyphCount;
604
605 UBiDi *fParaBidi;
606 UBiDi *fLineBidi;
607
608 le_int32 *fStyleRunLimits;
609 le_int32 *fStyleIndices;
610 StyleRunInfo *fStyleRunInfo;
611 le_int32 fStyleRunCount;
612
613 BreakIterator *fBreakIterator;
614 le_int32 fLineStart;
615 le_int32 fLineEnd;
616
617 le_int32 fFirstVisualRun;
618 le_int32 fLastVisualRun;
619 float fVisualRunLastX;
620 float fVisualRunLastY;
621 };
622
623 inline UBiDiLevel ParagraphLayout::getParagraphLevel()
624 {
625 return ubidi_getParaLevel(fParaBidi);
626 }
627
628 inline UBiDiDirection ParagraphLayout::getTextDirection()
629 {
630 return ubidi_getDirection(fParaBidi);
631 }
632
633 inline void ParagraphLayout::reflow()
634 {
635 fLineEnd = 0;
636 }
637
638 inline ParagraphLayout::Line::Line()
639 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL)
640 {
641 // nothing else to do
642 }
643
644 inline ParagraphLayout::Line::Line(const Line & /*other*/)
645 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL)
646 {
647 // nothing else to do
648 }
649
650 inline le_int32 ParagraphLayout::Line::countRuns() const
651 {
652 return fRunCount;
653 }
654
655 inline const LEFontInstance *ParagraphLayout::VisualRun::getFont() const
656 {
657 return fFont;
658 }
659
660 inline UBiDiDirection ParagraphLayout::VisualRun::getDirection() const
661 {
662 return fDirection;
663 }
664
665 inline le_int32 ParagraphLayout::VisualRun::getGlyphCount() const
666 {
667 return fGlyphCount;
668 }
669
670 inline const LEGlyphID *ParagraphLayout::VisualRun::getGlyphs() const
671 {
672 return fGlyphs;
673 }
674
675 inline const float *ParagraphLayout::VisualRun::getPositions() const
676 {
677 return fPositions;
678 }
679
680 inline const le_int32 *ParagraphLayout::VisualRun::getGlyphToCharMap() const
681 {
682 return fGlyphToCharMap;
683 }
684
685 inline le_int32 ParagraphLayout::VisualRun::getAscent() const
686 {
687 return fFont->getAscent();
688 }
689
690 inline le_int32 ParagraphLayout::VisualRun::getDescent() const
691 {
692 return fFont->getDescent();
693 }
694
695 inline le_int32 ParagraphLayout::VisualRun::getLeading() const
696 {
697 return fFont->getLeading();
698 }
699
700 inline ParagraphLayout::VisualRun::VisualRun()
701 : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL)
702 {
703 // nothing
704 }
705
706 inline ParagraphLayout::VisualRun::VisualRun(const VisualRun &other)
707 : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL)
708 {
709 // nothing
710 }
711
712 inline ParagraphLayout::VisualRun::VisualRun(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
713 const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[])
714 : fFont(font), fDirection(direction), fGlyphCount(glyphCount),
715 fGlyphs(glyphs), fPositions(positions), fGlyphToCharMap(glyphToCharMap)
716 {
717 // nothing else needs to be done!
718 }
719
720 U_NAMESPACE_END
721 #endif
722 #endif