]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
4 | * Copyright (C) 1999-2003, International Business Machines | |
5 | * Corporation and others. All Rights Reserved. | |
6 | * | |
7 | ******************************************************************************* | |
8 | * file name: Paragraph.cpp | |
9 | * | |
10 | * created on: 09/06/2000 | |
11 | * created by: Eric R. Mader | |
12 | */ | |
13 | ||
14 | #include "unicode/utypes.h" | |
15 | #include "unicode/uchar.h" | |
16 | #include "unicode/ubidi.h" | |
17 | ||
18 | #include "layout/ParagraphLayout.h" | |
19 | ||
20 | #include "RenderingSurface.h" | |
21 | #include "ScriptCompositeFontInstance.h" | |
22 | ||
23 | #include "paragraph.h" | |
24 | #include "UnicodeReader.h" | |
25 | #include "FontMap.h" | |
26 | ||
27 | #define MARGIN 10 | |
28 | #define LINE_GROW 32 | |
29 | ||
374ca955 | 30 | Paragraph::Paragraph(const LEUnicode chars[], int32_t charCount, const FontRuns *fontRuns, LEErrorCode &status) |
b75a7d8f A |
31 | : fParagraphLayout(NULL), fLineCount(0), fLinesMax(0), fLinesGrow(LINE_GROW), fLines(NULL), fChars(NULL), |
32 | fLineHeight(-1), fAscent(-1), fWidth(-1), fHeight(-1) | |
33 | { | |
374ca955 A |
34 | if (LE_FAILURE(status)) { |
35 | return; | |
36 | } | |
37 | ||
38 | LocaleRuns *locales = NULL; | |
39 | ||
b75a7d8f A |
40 | fChars = LE_NEW_ARRAY(LEUnicode, charCount); |
41 | LE_ARRAY_COPY(fChars, chars, charCount); | |
42 | ||
374ca955 A |
43 | fParagraphLayout = new ParagraphLayout(fChars, charCount, fontRuns, NULL, NULL, locales, UBIDI_DEFAULT_LTR, FALSE, status); |
44 | ||
45 | if (LE_FAILURE(status)) { | |
46 | return; | |
47 | } | |
b75a7d8f A |
48 | |
49 | le_int32 ascent = fParagraphLayout->getAscent(); | |
50 | le_int32 descent = fParagraphLayout->getDescent(); | |
51 | le_int32 leading = fParagraphLayout->getLeading(); | |
52 | ||
53 | fLineHeight = ascent + descent + leading; | |
54 | fAscent = ascent; | |
55 | } | |
56 | ||
57 | Paragraph::~Paragraph() | |
58 | { | |
59 | for (le_int32 line = 0; line < fLineCount; line += 1) { | |
60 | delete /*(LineInfo *)*/ fLines[line]; | |
61 | } | |
62 | ||
63 | LE_DELETE_ARRAY(fLines); | |
64 | delete fParagraphLayout; | |
65 | LE_DELETE_ARRAY(fChars); | |
66 | } | |
67 | ||
68 | void Paragraph::breakLines(le_int32 width, le_int32 height) | |
69 | { | |
70 | fHeight = height; | |
71 | ||
72 | // don't re-break if the width hasn't changed | |
73 | if (fWidth == width) { | |
74 | return; | |
75 | } | |
76 | ||
77 | fWidth = width; | |
78 | ||
79 | float lineWidth = (float) (width - 2 * MARGIN); | |
80 | const ParagraphLayout::Line *line; | |
81 | le_int32 li; | |
82 | ||
83 | // Free the old LineInfo's... | |
84 | for (li = 0; li < fLineCount; li += 1) { | |
85 | delete fLines[li]; | |
86 | } | |
87 | ||
88 | li = 0; | |
89 | fParagraphLayout->reflow(); | |
90 | while ((line = fParagraphLayout->nextLine(lineWidth)) != NULL) { | |
91 | // grow the line array, if we need to. | |
92 | if (li >= fLinesMax) { | |
93 | fLines = (const ParagraphLayout::Line **) LE_GROW_ARRAY(fLines, fLinesMax + fLinesGrow); | |
94 | fLinesMax += fLinesGrow; | |
95 | } | |
96 | ||
97 | fLines[li++] = line; | |
98 | } | |
99 | ||
100 | fLineCount = li; | |
101 | } | |
102 | ||
103 | void Paragraph::draw(RenderingSurface *surface, le_int32 firstLine, le_int32 lastLine) | |
104 | { | |
105 | le_int32 li, x, y; | |
106 | ||
107 | x = MARGIN; | |
108 | y = fAscent; | |
109 | ||
110 | for (li = firstLine; li <= lastLine; li += 1) { | |
111 | const ParagraphLayout::Line *line = fLines[li]; | |
112 | le_int32 runCount = line->countRuns(); | |
113 | le_int32 run; | |
114 | ||
374ca955 A |
115 | if (fParagraphLayout->getParagraphLevel() == UBIDI_RTL) { |
116 | le_int32 lastX = line->getWidth(); | |
117 | ||
118 | x = (fWidth - lastX - MARGIN); | |
119 | } | |
120 | ||
121 | ||
b75a7d8f A |
122 | for (run = 0; run < runCount; run += 1) { |
123 | const ParagraphLayout::VisualRun *visualRun = line->getVisualRun(run); | |
124 | le_int32 glyphCount = visualRun->getGlyphCount(); | |
125 | const LEFontInstance *font = visualRun->getFont(); | |
126 | const LEGlyphID *glyphs = visualRun->getGlyphs(); | |
127 | const float *positions = visualRun->getPositions(); | |
128 | ||
129 | surface->drawGlyphs(font, glyphs, glyphCount, positions, x, y, fWidth, fHeight); | |
130 | } | |
131 | ||
132 | y += fLineHeight; | |
133 | } | |
134 | } | |
135 | ||
136 | Paragraph *Paragraph::paragraphFactory(const char *fileName, const LEFontInstance *font, GUISupport *guiSupport) | |
137 | { | |
374ca955 | 138 | LEErrorCode status = LE_NO_ERROR; |
b75a7d8f A |
139 | le_int32 charCount; |
140 | const UChar *text = UnicodeReader::readFile(fileName, guiSupport, charCount); | |
141 | Paragraph *result = NULL; | |
142 | ||
143 | if (text == NULL) { | |
144 | return NULL; | |
145 | } | |
146 | ||
147 | FontRuns fontRuns(0); | |
148 | ||
149 | fontRuns.add(font, charCount); | |
150 | ||
374ca955 A |
151 | result = new Paragraph(text, charCount, &fontRuns, status); |
152 | ||
153 | if (LE_FAILURE(status)) { | |
154 | delete result; | |
155 | result = NULL; | |
156 | } | |
b75a7d8f A |
157 | |
158 | LE_DELETE_ARRAY(text); | |
159 | ||
160 | return result; | |
161 | } | |
162 |