]> git.saurik.com Git - apple/icu.git/blame - icuSources/samples/layout/paragraph.cpp
ICU-6.2.22.tar.gz
[apple/icu.git] / icuSources / samples / layout / paragraph.cpp
CommitLineData
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 30Paragraph::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
57Paragraph::~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
68void 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
103void 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
136Paragraph *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