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