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