1 /*
2 **********************************************************************
3 * Copyright (C) 2002-2005, 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 */
getStaticClassID()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 */
getDynamicClassID()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 */
getStaticClassID()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 */
getDynamicClassID()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 /**
503 * Return a <code>ParagraphLayout::Line</code> object which represents next line
504 * in the paragraph. The width of the line is specified each time so that it can
505 * be varied to support arbitrary paragraph shapes.
506 *
507 * @param width is the width of the line. If <code>width</code> is less than or equal
508 * to zero, a <code>ParagraphLayout::Line</code> object representing the
509 * rest of the paragraph will be returned.
510 *
511 * @return a <code>ParagraphLayout::Line</code> object which represents the line. The caller
512 * is responsible for deleting the object. Returns <code>NULL</code> if there are no
513 * more lines in the paragraph.
514 *
515 * @see ParagraphLayout::Line
516 *
517 * @stable ICU 3.2
518 */
519 Line *nextLine(float width);
520
521 /**
522 * ICU "poor man's RTTI", returns a UClassID for this class.
523 *
524 * @stable ICU 3.2
525 */
getStaticClassID()526 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
527
528 /**
529 * ICU "poor man's RTTI", returns a UClassID for the actual class.
530 *
531 * @stable ICU 3.2
532 */
getDynamicClassID()533 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
534
535 private:
536
537
538 /**
539 * The address of this static class variable serves as this class's ID
540 * for ICU "poor man's RTTI".
541 */
542 static const char fgClassID;
543
544 struct StyleRunInfo
545 {
546 LayoutEngine *engine;
547 const LEFontInstance *font;
548 const Locale *locale;
549 LEGlyphID *glyphs;
550 float *positions;
551 UScriptCode script;
552 UBiDiLevel level;
553 le_int32 runBase;
554 le_int32 runLimit;
555 le_int32 glyphBase;
556 le_int32 glyphCount;
557 };
558
ParagraphLayout()559 ParagraphLayout() {};
ParagraphLayout(const ParagraphLayout &)560 ParagraphLayout(const ParagraphLayout & /*other*/) : UObject( ){};
561 inline ParagraphLayout &operator=(const ParagraphLayout & /*other*/) { return *this; };
562
563 void computeLevels(UBiDiLevel paragraphLevel);
564
565 Line *computeVisualRuns();
566 void appendRun(Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar);
567
568 void computeScripts();
569
570 void computeLocales();
571
572 void computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status);
573
574 void computeMetrics();
575
576 le_int32 getLanguageCode(const Locale *locale);
577
578 le_int32 getCharRun(le_int32 charIndex);
579
580 static le_bool isComplex(UScriptCode script);
581
582 le_int32 previousBreak(le_int32 charIndex);
583
584
585 const LEUnicode *fChars;
586 le_int32 fCharCount;
587
588 const FontRuns *fFontRuns;
589 const ValueRuns *fLevelRuns;
590 const ValueRuns *fScriptRuns;
591 const LocaleRuns *fLocaleRuns;
592
593 le_bool fVertical;
594 le_bool fClientLevels;
595 le_bool fClientScripts;
596 le_bool fClientLocales;
597
598 UBiDiLevel *fEmbeddingLevels;
599
600 le_int32 fAscent;
601 le_int32 fDescent;
602 le_int32 fLeading;
603
604 le_int32 *fGlyphToCharMap;
605 le_int32 *fCharToMinGlyphMap;
606 le_int32 *fCharToMaxGlyphMap;
607 float *fGlyphWidths;
608 le_int32 fGlyphCount;
609
610 UBiDi *fParaBidi;
611 UBiDi *fLineBidi;
612
613 le_int32 *fStyleRunLimits;
614 le_int32 *fStyleIndices;
615 StyleRunInfo *fStyleRunInfo;
616 le_int32 fStyleRunCount;
617
618 BreakIterator *fBreakIterator;
619 le_int32 fLineStart;
620 le_int32 fLineEnd;
621
622 le_int32 fFirstVisualRun;
623 le_int32 fLastVisualRun;
624 float fVisualRunLastX;
625 float fVisualRunLastY;
626 };
627
getParagraphLevel()628 inline UBiDiLevel ParagraphLayout::getParagraphLevel()
629 {
630 return ubidi_getParaLevel(fParaBidi);
631 }
632
getTextDirection()633 inline UBiDiDirection ParagraphLayout::getTextDirection()
634 {
635 return ubidi_getDirection(fParaBidi);
636 }
637
reflow()638 inline void ParagraphLayout::reflow()
639 {
640 fLineEnd = 0;
641 }
642
Line()643 inline ParagraphLayout::Line::Line()
644 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL)
645 {
646 // nothing else to do
647 }
648
Line(const Line &)649 inline ParagraphLayout::Line::Line(const Line & /*other*/)
650 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL)
651 {
652 // nothing else to do
653 }
654
countRuns()655 inline le_int32 ParagraphLayout::Line::countRuns() const
656 {
657 return fRunCount;
658 }
659
getFont()660 inline const LEFontInstance *ParagraphLayout::VisualRun::getFont() const
661 {
662 return fFont;
663 }
664
getDirection()665 inline UBiDiDirection ParagraphLayout::VisualRun::getDirection() const
666 {
667 return fDirection;
668 }
669
getGlyphCount()670 inline le_int32 ParagraphLayout::VisualRun::getGlyphCount() const
671 {
672 return fGlyphCount;
673 }
674
getGlyphs()675 inline const LEGlyphID *ParagraphLayout::VisualRun::getGlyphs() const
676 {
677 return fGlyphs;
678 }
679
getPositions()680 inline const float *ParagraphLayout::VisualRun::getPositions() const
681 {
682 return fPositions;
683 }
684
getGlyphToCharMap()685 inline const le_int32 *ParagraphLayout::VisualRun::getGlyphToCharMap() const
686 {
687 return fGlyphToCharMap;
688 }
689
getAscent()690 inline le_int32 ParagraphLayout::VisualRun::getAscent() const
691 {
692 return fFont->getAscent();
693 }
694
getDescent()695 inline le_int32 ParagraphLayout::VisualRun::getDescent() const
696 {
697 return fFont->getDescent();
698 }
699
getLeading()700 inline le_int32 ParagraphLayout::VisualRun::getLeading() const
701 {
702 return fFont->getLeading();
703 }
704
VisualRun()705 inline ParagraphLayout::VisualRun::VisualRun()
706 : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL)
707 {
708 // nothing
709 }
710
VisualRun(const VisualRun &)711 inline ParagraphLayout::VisualRun::VisualRun(const VisualRun &/*other*/)
712 : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL)
713 {
714 // nothing
715 }
716
VisualRun(const LEFontInstance * font,UBiDiDirection direction,le_int32 glyphCount,const LEGlyphID glyphs[],const float positions[],const le_int32 glyphToCharMap[])717 inline ParagraphLayout::VisualRun::VisualRun(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
718 const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[])
719 : fFont(font), fDirection(direction), fGlyphCount(glyphCount),
720 fGlyphs(glyphs), fPositions(positions), fGlyphToCharMap(glyphToCharMap)
721 {
722 // nothing else needs to be done!
723 }
724
725 U_NAMESPACE_END
726 #endif
727 #endif
728