1*0e209d39SAndroid Build Coastguard Worker // © 2016 and later: Unicode, Inc. and others.
2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html
3*0e209d39SAndroid Build Coastguard Worker /*
4*0e209d39SAndroid Build Coastguard Worker *******************************************************************************
5*0e209d39SAndroid Build Coastguard Worker *
6*0e209d39SAndroid Build Coastguard Worker * Copyright (C) 1999-2014, International Business Machines
7*0e209d39SAndroid Build Coastguard Worker * Corporation and others. All Rights Reserved.
8*0e209d39SAndroid Build Coastguard Worker *
9*0e209d39SAndroid Build Coastguard Worker *******************************************************************************
10*0e209d39SAndroid Build Coastguard Worker */
11*0e209d39SAndroid Build Coastguard Worker
12*0e209d39SAndroid Build Coastguard Worker #ifndef USING_ICULEHB /* C API not available under HB */
13*0e209d39SAndroid Build Coastguard Worker
14*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h"
15*0e209d39SAndroid Build Coastguard Worker #include "unicode/ubidi.h"
16*0e209d39SAndroid Build Coastguard Worker #include "unicode/uscript.h"
17*0e209d39SAndroid Build Coastguard Worker #include "unicode/ctest.h"
18*0e209d39SAndroid Build Coastguard Worker
19*0e209d39SAndroid Build Coastguard Worker #include "layout/LETypes.h"
20*0e209d39SAndroid Build Coastguard Worker #include "layout/LEScripts.h"
21*0e209d39SAndroid Build Coastguard Worker #include "layout/loengine.h"
22*0e209d39SAndroid Build Coastguard Worker
23*0e209d39SAndroid Build Coastguard Worker #include "layout/playout.h"
24*0e209d39SAndroid Build Coastguard Worker #include "layout/plruns.h"
25*0e209d39SAndroid Build Coastguard Worker
26*0e209d39SAndroid Build Coastguard Worker #include "cfonts.h"
27*0e209d39SAndroid Build Coastguard Worker
28*0e209d39SAndroid Build Coastguard Worker #include "letest.h"
29*0e209d39SAndroid Build Coastguard Worker
30*0e209d39SAndroid Build Coastguard Worker #include "sfnt.h"
31*0e209d39SAndroid Build Coastguard Worker #include "xmlreader.h"
32*0e209d39SAndroid Build Coastguard Worker #include "putilimp.h" /* for U_FILE_SEP_STRING */
33*0e209d39SAndroid Build Coastguard Worker
34*0e209d39SAndroid Build Coastguard Worker #include <stdlib.h>
35*0e209d39SAndroid Build Coastguard Worker #include <stdio.h>
36*0e209d39SAndroid Build Coastguard Worker #include <string.h>
37*0e209d39SAndroid Build Coastguard Worker
38*0e209d39SAndroid Build Coastguard Worker #define CH_COMMA 0x002C
39*0e209d39SAndroid Build Coastguard Worker
40*0e209d39SAndroid Build Coastguard Worker U_CDECL_BEGIN
ParamTest(void)41*0e209d39SAndroid Build Coastguard Worker static void U_CALLCONV ParamTest(void)
42*0e209d39SAndroid Build Coastguard Worker {
43*0e209d39SAndroid Build Coastguard Worker LEErrorCode status = LE_NO_ERROR;
44*0e209d39SAndroid Build Coastguard Worker le_font *font = le_simpleFontOpen(12, &status);
45*0e209d39SAndroid Build Coastguard Worker le_engine *engine = le_create(font, arabScriptCode, -1, 0, &status);
46*0e209d39SAndroid Build Coastguard Worker LEGlyphID *glyphs = NULL;
47*0e209d39SAndroid Build Coastguard Worker le_int32 *indices = NULL;
48*0e209d39SAndroid Build Coastguard Worker float *positions = NULL;
49*0e209d39SAndroid Build Coastguard Worker le_int32 glyphCount = 0;
50*0e209d39SAndroid Build Coastguard Worker
51*0e209d39SAndroid Build Coastguard Worker float x = 0.0, y = 0.0;
52*0e209d39SAndroid Build Coastguard Worker LEUnicode chars[] = {
53*0e209d39SAndroid Build Coastguard Worker 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, 0x0020, /* "English " */
54*0e209d39SAndroid Build Coastguard Worker 0x0645, 0x0627, 0x0646, 0x062A, 0x0648, 0x0634, /* MEM ALIF KAF NOON TEH WAW SHEEN */
55*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x02E /* " text." */
56*0e209d39SAndroid Build Coastguard Worker };
57*0e209d39SAndroid Build Coastguard Worker
58*0e209d39SAndroid Build Coastguard Worker
59*0e209d39SAndroid Build Coastguard Worker glyphCount = le_getGlyphCount(engine, &status);
60*0e209d39SAndroid Build Coastguard Worker if (glyphCount != 0) {
61*0e209d39SAndroid Build Coastguard Worker log_err("Calling getGlyphCount() on an empty layout returned %d.\n", glyphCount);
62*0e209d39SAndroid Build Coastguard Worker }
63*0e209d39SAndroid Build Coastguard Worker
64*0e209d39SAndroid Build Coastguard Worker glyphs = NEW_ARRAY(LEGlyphID, glyphCount + 10);
65*0e209d39SAndroid Build Coastguard Worker indices = NEW_ARRAY(le_int32, glyphCount + 10);
66*0e209d39SAndroid Build Coastguard Worker positions = NEW_ARRAY(float, glyphCount + 10);
67*0e209d39SAndroid Build Coastguard Worker
68*0e209d39SAndroid Build Coastguard Worker le_getGlyphs(engine, NULL, &status);
69*0e209d39SAndroid Build Coastguard Worker
70*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
71*0e209d39SAndroid Build Coastguard Worker log_err("Calling getGlyphs(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n");
72*0e209d39SAndroid Build Coastguard Worker }
73*0e209d39SAndroid Build Coastguard Worker
74*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
75*0e209d39SAndroid Build Coastguard Worker le_getGlyphs(engine, glyphs, &status);
76*0e209d39SAndroid Build Coastguard Worker
77*0e209d39SAndroid Build Coastguard Worker if (status != LE_NO_LAYOUT_ERROR) {
78*0e209d39SAndroid Build Coastguard Worker log_err("Calling getGlyphs(glyphs, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n");
79*0e209d39SAndroid Build Coastguard Worker }
80*0e209d39SAndroid Build Coastguard Worker
81*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
82*0e209d39SAndroid Build Coastguard Worker le_getCharIndices(engine, NULL, &status);
83*0e209d39SAndroid Build Coastguard Worker
84*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
85*0e209d39SAndroid Build Coastguard Worker log_err("Calling getCharIndices(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n");
86*0e209d39SAndroid Build Coastguard Worker }
87*0e209d39SAndroid Build Coastguard Worker
88*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
89*0e209d39SAndroid Build Coastguard Worker le_getCharIndices(engine, indices, &status);
90*0e209d39SAndroid Build Coastguard Worker
91*0e209d39SAndroid Build Coastguard Worker if (status != LE_NO_LAYOUT_ERROR) {
92*0e209d39SAndroid Build Coastguard Worker log_err("Calling getCharIndices(indices, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n");
93*0e209d39SAndroid Build Coastguard Worker }
94*0e209d39SAndroid Build Coastguard Worker
95*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
96*0e209d39SAndroid Build Coastguard Worker le_getCharIndicesWithBase(engine, NULL, 1024, &status);
97*0e209d39SAndroid Build Coastguard Worker
98*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
99*0e209d39SAndroid Build Coastguard Worker log_err("Calling getCharIndices(NULL, 1024, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n");
100*0e209d39SAndroid Build Coastguard Worker }
101*0e209d39SAndroid Build Coastguard Worker
102*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
103*0e209d39SAndroid Build Coastguard Worker le_getCharIndicesWithBase(engine, indices, 1024, &status);
104*0e209d39SAndroid Build Coastguard Worker
105*0e209d39SAndroid Build Coastguard Worker if (status != LE_NO_LAYOUT_ERROR) {
106*0e209d39SAndroid Build Coastguard Worker log_err("Calling getCharIndices(indices, 1024, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n");
107*0e209d39SAndroid Build Coastguard Worker }
108*0e209d39SAndroid Build Coastguard Worker
109*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
110*0e209d39SAndroid Build Coastguard Worker le_getGlyphPositions(engine, NULL, &status);
111*0e209d39SAndroid Build Coastguard Worker
112*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
113*0e209d39SAndroid Build Coastguard Worker log_err("Calling getGlyphPositions(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n");
114*0e209d39SAndroid Build Coastguard Worker }
115*0e209d39SAndroid Build Coastguard Worker
116*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
117*0e209d39SAndroid Build Coastguard Worker le_getGlyphPositions(engine, positions, &status);
118*0e209d39SAndroid Build Coastguard Worker
119*0e209d39SAndroid Build Coastguard Worker if (status != LE_NO_LAYOUT_ERROR) {
120*0e209d39SAndroid Build Coastguard Worker log_err("Calling getGlyphPositions(positions, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n");
121*0e209d39SAndroid Build Coastguard Worker }
122*0e209d39SAndroid Build Coastguard Worker
123*0e209d39SAndroid Build Coastguard Worker DELETE_ARRAY(positions);
124*0e209d39SAndroid Build Coastguard Worker DELETE_ARRAY(indices);
125*0e209d39SAndroid Build Coastguard Worker DELETE_ARRAY(glyphs);
126*0e209d39SAndroid Build Coastguard Worker
127*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
128*0e209d39SAndroid Build Coastguard Worker glyphCount = le_layoutChars(engine, NULL, 0, 0, 0, false, 0.0, 0.0, &status);
129*0e209d39SAndroid Build Coastguard Worker
130*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
131*0e209d39SAndroid Build Coastguard Worker log_err("Calling layoutChars(NULL, 0, 0, 0, false, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
132*0e209d39SAndroid Build Coastguard Worker }
133*0e209d39SAndroid Build Coastguard Worker
134*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
135*0e209d39SAndroid Build Coastguard Worker glyphCount = le_layoutChars(engine, chars, -1, 6, 20, true, 0.0, 0.0, &status);
136*0e209d39SAndroid Build Coastguard Worker
137*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
138*0e209d39SAndroid Build Coastguard Worker log_err("Calling layoutChars(chars, -1, 6, 20, true, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
139*0e209d39SAndroid Build Coastguard Worker }
140*0e209d39SAndroid Build Coastguard Worker
141*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
142*0e209d39SAndroid Build Coastguard Worker glyphCount = le_layoutChars(engine, chars, 8, -1, 20, true, 0.0, 0.0, &status);
143*0e209d39SAndroid Build Coastguard Worker
144*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
145*0e209d39SAndroid Build Coastguard Worker log_err("Calling layoutChars(chars, 8, -1, 20, true, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
146*0e209d39SAndroid Build Coastguard Worker }
147*0e209d39SAndroid Build Coastguard Worker
148*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
149*0e209d39SAndroid Build Coastguard Worker glyphCount = le_layoutChars(engine, chars, 8, 6, -1, true, 0.0, 0.0, &status);
150*0e209d39SAndroid Build Coastguard Worker
151*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
152*0e209d39SAndroid Build Coastguard Worker log_err("Calling layoutChars((chars, 8, 6, -1, true, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
153*0e209d39SAndroid Build Coastguard Worker }
154*0e209d39SAndroid Build Coastguard Worker
155*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
156*0e209d39SAndroid Build Coastguard Worker glyphCount = le_layoutChars(engine, chars, 8, 6, 10, true, 0.0, 0.0, &status);
157*0e209d39SAndroid Build Coastguard Worker
158*0e209d39SAndroid Build Coastguard Worker if (status != LE_ILLEGAL_ARGUMENT_ERROR) {
159*0e209d39SAndroid Build Coastguard Worker log_err("Calling layoutChars(chars, 8, 6, 10, true, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n");
160*0e209d39SAndroid Build Coastguard Worker }
161*0e209d39SAndroid Build Coastguard Worker
162*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
163*0e209d39SAndroid Build Coastguard Worker glyphCount = le_layoutChars(engine, chars, 8, 6, 20, true, 0.0, 0.0, &status);
164*0e209d39SAndroid Build Coastguard Worker
165*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
166*0e209d39SAndroid Build Coastguard Worker log_err("Calling layoutChars(chars, 8, 6, 20, true, 0.0, 0.0, status) failed.\n");
167*0e209d39SAndroid Build Coastguard Worker goto bail;
168*0e209d39SAndroid Build Coastguard Worker }
169*0e209d39SAndroid Build Coastguard Worker
170*0e209d39SAndroid Build Coastguard Worker le_getGlyphPosition(engine, -1, &x, &y, &status);
171*0e209d39SAndroid Build Coastguard Worker
172*0e209d39SAndroid Build Coastguard Worker if (status != LE_INDEX_OUT_OF_BOUNDS_ERROR) {
173*0e209d39SAndroid Build Coastguard Worker log_err("Calling getGlyphPosition(-1, x, y, status) did not fail w/ LE_INDEX_OUT_OF_BOUNDS_ERROR.\n");
174*0e209d39SAndroid Build Coastguard Worker }
175*0e209d39SAndroid Build Coastguard Worker
176*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
177*0e209d39SAndroid Build Coastguard Worker le_getGlyphPosition(engine, glyphCount + 1, &x, &y, &status);
178*0e209d39SAndroid Build Coastguard Worker
179*0e209d39SAndroid Build Coastguard Worker if (status != LE_INDEX_OUT_OF_BOUNDS_ERROR) {
180*0e209d39SAndroid Build Coastguard Worker log_err("Calling getGlyphPosition(glyphCount + 1, x, y, status) did not fail w/ LE_INDEX_OUT_OF_BOUNDS_ERROR.\n");
181*0e209d39SAndroid Build Coastguard Worker }
182*0e209d39SAndroid Build Coastguard Worker
183*0e209d39SAndroid Build Coastguard Worker bail:
184*0e209d39SAndroid Build Coastguard Worker le_close(engine);
185*0e209d39SAndroid Build Coastguard Worker le_fontClose(font);
186*0e209d39SAndroid Build Coastguard Worker }
187*0e209d39SAndroid Build Coastguard Worker U_CDECL_END
188*0e209d39SAndroid Build Coastguard Worker
189*0e209d39SAndroid Build Coastguard Worker U_CDECL_BEGIN
FactoryTest(void)190*0e209d39SAndroid Build Coastguard Worker static void U_CALLCONV FactoryTest(void)
191*0e209d39SAndroid Build Coastguard Worker {
192*0e209d39SAndroid Build Coastguard Worker LEErrorCode status = LE_NO_ERROR;
193*0e209d39SAndroid Build Coastguard Worker le_font *font = le_simpleFontOpen(12, &status);
194*0e209d39SAndroid Build Coastguard Worker le_engine *engine = NULL;
195*0e209d39SAndroid Build Coastguard Worker le_int32 scriptCode;
196*0e209d39SAndroid Build Coastguard Worker
197*0e209d39SAndroid Build Coastguard Worker for(scriptCode = 0; scriptCode < scriptCodeCount; scriptCode += 1) {
198*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
199*0e209d39SAndroid Build Coastguard Worker engine = le_create(font, scriptCode, -1, 0, &status);
200*0e209d39SAndroid Build Coastguard Worker
201*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
202*0e209d39SAndroid Build Coastguard Worker log_err("Could not create a LayoutEngine for script \'%s\'.\n", uscript_getShortName((UScriptCode)scriptCode));
203*0e209d39SAndroid Build Coastguard Worker }
204*0e209d39SAndroid Build Coastguard Worker
205*0e209d39SAndroid Build Coastguard Worker le_close(engine);
206*0e209d39SAndroid Build Coastguard Worker }
207*0e209d39SAndroid Build Coastguard Worker
208*0e209d39SAndroid Build Coastguard Worker le_fontClose(font);
209*0e209d39SAndroid Build Coastguard Worker }
210*0e209d39SAndroid Build Coastguard Worker U_CDECL_END
211*0e209d39SAndroid Build Coastguard Worker
212*0e209d39SAndroid Build Coastguard Worker U_CDECL_BEGIN
AccessTest(void)213*0e209d39SAndroid Build Coastguard Worker static void U_CALLCONV AccessTest(void)
214*0e209d39SAndroid Build Coastguard Worker {
215*0e209d39SAndroid Build Coastguard Worker LEErrorCode status = LE_NO_ERROR;
216*0e209d39SAndroid Build Coastguard Worker le_font *font = le_simpleFontOpen(12, &status);
217*0e209d39SAndroid Build Coastguard Worker le_engine *engine =le_create(font, arabScriptCode, -1, 0, &status);
218*0e209d39SAndroid Build Coastguard Worker le_int32 glyphCount;
219*0e209d39SAndroid Build Coastguard Worker LEGlyphID glyphs[6];
220*0e209d39SAndroid Build Coastguard Worker le_int32 biasedIndices[6], indices[6], glyph;
221*0e209d39SAndroid Build Coastguard Worker float positions[6 * 2 + 2];
222*0e209d39SAndroid Build Coastguard Worker LEUnicode chars[] = {
223*0e209d39SAndroid Build Coastguard Worker 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, 0x0020, /* "English " */
224*0e209d39SAndroid Build Coastguard Worker 0x0645, 0x0627, 0x0646, 0x062A, 0x0648, 0x0634, /* MEM ALIF KAF NOON TEH WAW SHEEN */
225*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x02E /* " text." */
226*0e209d39SAndroid Build Coastguard Worker };
227*0e209d39SAndroid Build Coastguard Worker
228*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
229*0e209d39SAndroid Build Coastguard Worker log_err("Could not create LayoutEngine.\n");
230*0e209d39SAndroid Build Coastguard Worker goto bail;
231*0e209d39SAndroid Build Coastguard Worker }
232*0e209d39SAndroid Build Coastguard Worker
233*0e209d39SAndroid Build Coastguard Worker glyphCount = le_layoutChars(engine, chars, 8, 6, 20, true, 0.0, 0.0, &status);
234*0e209d39SAndroid Build Coastguard Worker
235*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status) || glyphCount != 6) {
236*0e209d39SAndroid Build Coastguard Worker log_err("layoutChars(chars, 8, 6, 20, true, 0.0, 0.0, status) failed.\n");
237*0e209d39SAndroid Build Coastguard Worker goto bail;
238*0e209d39SAndroid Build Coastguard Worker }
239*0e209d39SAndroid Build Coastguard Worker
240*0e209d39SAndroid Build Coastguard Worker le_getGlyphs(engine, glyphs, &status);
241*0e209d39SAndroid Build Coastguard Worker le_getCharIndices(engine, indices, &status);
242*0e209d39SAndroid Build Coastguard Worker le_getGlyphPositions(engine, positions, &status);
243*0e209d39SAndroid Build Coastguard Worker
244*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
245*0e209d39SAndroid Build Coastguard Worker log_err("Could not get glyph, indices and position arrays.\n");
246*0e209d39SAndroid Build Coastguard Worker goto bail;
247*0e209d39SAndroid Build Coastguard Worker }
248*0e209d39SAndroid Build Coastguard Worker
249*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
250*0e209d39SAndroid Build Coastguard Worker le_getCharIndicesWithBase(engine, biasedIndices, 1024, &status);
251*0e209d39SAndroid Build Coastguard Worker
252*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
253*0e209d39SAndroid Build Coastguard Worker log_err("getCharIndices(biasedIndices, 1024, status) failed.\n");
254*0e209d39SAndroid Build Coastguard Worker } else {
255*0e209d39SAndroid Build Coastguard Worker for (glyph = 0; glyph < glyphCount; glyph += 1) {
256*0e209d39SAndroid Build Coastguard Worker if (biasedIndices[glyph] != (indices[glyph] + 1024)) {
257*0e209d39SAndroid Build Coastguard Worker log_err("biasedIndices[%d] != indices[%d] + 1024: %8X, %8X\n",
258*0e209d39SAndroid Build Coastguard Worker glyph, glyph, biasedIndices[glyph], indices[glyph]);
259*0e209d39SAndroid Build Coastguard Worker break;
260*0e209d39SAndroid Build Coastguard Worker }
261*0e209d39SAndroid Build Coastguard Worker }
262*0e209d39SAndroid Build Coastguard Worker }
263*0e209d39SAndroid Build Coastguard Worker
264*0e209d39SAndroid Build Coastguard Worker status = LE_NO_ERROR;
265*0e209d39SAndroid Build Coastguard Worker for (glyph = 0; glyph <= glyphCount; glyph += 1) {
266*0e209d39SAndroid Build Coastguard Worker float x = 0.0, y = 0.0;
267*0e209d39SAndroid Build Coastguard Worker
268*0e209d39SAndroid Build Coastguard Worker le_getGlyphPosition(engine, glyph, &x, &y, &status);
269*0e209d39SAndroid Build Coastguard Worker
270*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
271*0e209d39SAndroid Build Coastguard Worker log_err("getGlyphPosition(%d, x, y, status) failed.\n", glyph);
272*0e209d39SAndroid Build Coastguard Worker break;
273*0e209d39SAndroid Build Coastguard Worker }
274*0e209d39SAndroid Build Coastguard Worker
275*0e209d39SAndroid Build Coastguard Worker if (x != positions[glyph*2] || y != positions[glyph*2 + 1]) {
276*0e209d39SAndroid Build Coastguard Worker log_err("getGlyphPosition(%d, x, y, status) returned bad position: (%f, %f) != (%f, %f)\n",
277*0e209d39SAndroid Build Coastguard Worker glyph, x, y, positions[glyph*2], positions[glyph*2 + 1]);
278*0e209d39SAndroid Build Coastguard Worker break;
279*0e209d39SAndroid Build Coastguard Worker }
280*0e209d39SAndroid Build Coastguard Worker }
281*0e209d39SAndroid Build Coastguard Worker
282*0e209d39SAndroid Build Coastguard Worker bail:
283*0e209d39SAndroid Build Coastguard Worker le_close(engine);
284*0e209d39SAndroid Build Coastguard Worker le_fontClose(font);
285*0e209d39SAndroid Build Coastguard Worker }
286*0e209d39SAndroid Build Coastguard Worker U_CDECL_END
287*0e209d39SAndroid Build Coastguard Worker
compareResults(const char * testID,TestResult * expected,TestResult * actual)288*0e209d39SAndroid Build Coastguard Worker static le_bool compareResults(const char *testID, TestResult *expected, TestResult *actual)
289*0e209d39SAndroid Build Coastguard Worker {
290*0e209d39SAndroid Build Coastguard Worker le_int32 i;
291*0e209d39SAndroid Build Coastguard Worker
292*0e209d39SAndroid Build Coastguard Worker /* NOTE: we'll stop on the first failure 'cause once there's one error, it may cascade... */
293*0e209d39SAndroid Build Coastguard Worker if (actual->glyphCount != expected->glyphCount) {
294*0e209d39SAndroid Build Coastguard Worker log_err("Test %s: incorrect glyph count: expected %d, got %d\n",
295*0e209d39SAndroid Build Coastguard Worker testID, expected->glyphCount, actual->glyphCount);
296*0e209d39SAndroid Build Coastguard Worker return false;
297*0e209d39SAndroid Build Coastguard Worker }
298*0e209d39SAndroid Build Coastguard Worker
299*0e209d39SAndroid Build Coastguard Worker for (i = 0; i < actual->glyphCount; i += 1) {
300*0e209d39SAndroid Build Coastguard Worker if (actual->glyphs[i] != expected->glyphs[i]) {
301*0e209d39SAndroid Build Coastguard Worker log_err("Test %s: incorrect id for glyph %d: expected %4X, got %4X\n",
302*0e209d39SAndroid Build Coastguard Worker testID, i, expected->glyphs[i], actual->glyphs[i]);
303*0e209d39SAndroid Build Coastguard Worker return false;
304*0e209d39SAndroid Build Coastguard Worker }
305*0e209d39SAndroid Build Coastguard Worker }
306*0e209d39SAndroid Build Coastguard Worker
307*0e209d39SAndroid Build Coastguard Worker for (i = 0; i < actual->glyphCount; i += 1) {
308*0e209d39SAndroid Build Coastguard Worker if (actual->indices[i] != expected->indices[i]) {
309*0e209d39SAndroid Build Coastguard Worker log_err("Test %s: incorrect index for glyph %d: expected %8X, got %8X\n",
310*0e209d39SAndroid Build Coastguard Worker testID, i, expected->indices[i], actual->indices[i]);
311*0e209d39SAndroid Build Coastguard Worker return false;
312*0e209d39SAndroid Build Coastguard Worker }
313*0e209d39SAndroid Build Coastguard Worker }
314*0e209d39SAndroid Build Coastguard Worker
315*0e209d39SAndroid Build Coastguard Worker for (i = 0; i <= actual->glyphCount; i += 1) {
316*0e209d39SAndroid Build Coastguard Worker double xError = uprv_fabs(actual->positions[i * 2] - expected->positions[i * 2]);
317*0e209d39SAndroid Build Coastguard Worker double yError = uprv_fabs(actual->positions[i * 2 + 1] - expected->positions[i * 2 + 1]);
318*0e209d39SAndroid Build Coastguard Worker
319*0e209d39SAndroid Build Coastguard Worker if (xError > 0.0001) {
320*0e209d39SAndroid Build Coastguard Worker log_err("Test %s: incorrect x position for glyph %d: expected %f, got %f\n",
321*0e209d39SAndroid Build Coastguard Worker testID, i, expected->positions[i * 2], actual->positions[i * 2]);
322*0e209d39SAndroid Build Coastguard Worker return false;
323*0e209d39SAndroid Build Coastguard Worker }
324*0e209d39SAndroid Build Coastguard Worker
325*0e209d39SAndroid Build Coastguard Worker if (yError < 0) {
326*0e209d39SAndroid Build Coastguard Worker yError = -yError;
327*0e209d39SAndroid Build Coastguard Worker }
328*0e209d39SAndroid Build Coastguard Worker
329*0e209d39SAndroid Build Coastguard Worker if (yError > 0.0001) {
330*0e209d39SAndroid Build Coastguard Worker log_err("Test %s: incorrect y position for glyph %d: expected %f, got %f\n",
331*0e209d39SAndroid Build Coastguard Worker testID, i, expected->positions[i * 2 + 1], actual->positions[i * 2 + 1]);
332*0e209d39SAndroid Build Coastguard Worker return false;
333*0e209d39SAndroid Build Coastguard Worker }
334*0e209d39SAndroid Build Coastguard Worker }
335*0e209d39SAndroid Build Coastguard Worker
336*0e209d39SAndroid Build Coastguard Worker return true;
337*0e209d39SAndroid Build Coastguard Worker }
338*0e209d39SAndroid Build Coastguard Worker
checkFontVersion(le_font * font,const char * testVersionString,le_uint32 testChecksum,const char * testID)339*0e209d39SAndroid Build Coastguard Worker static void checkFontVersion(le_font *font, const char *testVersionString,
340*0e209d39SAndroid Build Coastguard Worker le_uint32 testChecksum, const char *testID)
341*0e209d39SAndroid Build Coastguard Worker {
342*0e209d39SAndroid Build Coastguard Worker le_uint32 fontChecksum = le_getFontChecksum(font);
343*0e209d39SAndroid Build Coastguard Worker
344*0e209d39SAndroid Build Coastguard Worker if (fontChecksum != testChecksum) {
345*0e209d39SAndroid Build Coastguard Worker const char *fontVersionString = le_getNameString(font, NAME_VERSION_STRING,
346*0e209d39SAndroid Build Coastguard Worker PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
347*0e209d39SAndroid Build Coastguard Worker const LEUnicode16 *uFontVersionString = NULL;
348*0e209d39SAndroid Build Coastguard Worker
349*0e209d39SAndroid Build Coastguard Worker if (fontVersionString == NULL) {
350*0e209d39SAndroid Build Coastguard Worker uFontVersionString = le_getUnicodeNameString(font, NAME_VERSION_STRING,
351*0e209d39SAndroid Build Coastguard Worker PLATFORM_MICROSOFT, MICROSOFT_UNICODE_BMP, MICROSOFT_ENGLISH);
352*0e209d39SAndroid Build Coastguard Worker }
353*0e209d39SAndroid Build Coastguard Worker
354*0e209d39SAndroid Build Coastguard Worker log_info("Test %s: this may not be the same font used to generate the test data.\n", testID);
355*0e209d39SAndroid Build Coastguard Worker
356*0e209d39SAndroid Build Coastguard Worker if (uFontVersionString != NULL) {
357*0e209d39SAndroid Build Coastguard Worker log_info("Your font's version string is \"%S\"\n", uFontVersionString);
358*0e209d39SAndroid Build Coastguard Worker le_deleteUnicodeNameString(font, uFontVersionString);
359*0e209d39SAndroid Build Coastguard Worker } else {
360*0e209d39SAndroid Build Coastguard Worker log_info("Your font's version string is \"%s\"\n", fontVersionString);
361*0e209d39SAndroid Build Coastguard Worker le_deleteNameString(font, fontVersionString);
362*0e209d39SAndroid Build Coastguard Worker }
363*0e209d39SAndroid Build Coastguard Worker
364*0e209d39SAndroid Build Coastguard Worker log_info("The expected version string is \"%s\"\n", testVersionString);
365*0e209d39SAndroid Build Coastguard Worker log_info("If you see errors, they may be due to the version of the font you're using.\n");
366*0e209d39SAndroid Build Coastguard Worker }
367*0e209d39SAndroid Build Coastguard Worker }
368*0e209d39SAndroid Build Coastguard Worker
369*0e209d39SAndroid Build Coastguard Worker /* Returns the path to icu/source/test/testdata/ */
getSourceTestData()370*0e209d39SAndroid Build Coastguard Worker static const char *getSourceTestData() {
371*0e209d39SAndroid Build Coastguard Worker #ifdef U_TOPSRCDIR
372*0e209d39SAndroid Build Coastguard Worker const char *srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
373*0e209d39SAndroid Build Coastguard Worker #else
374*0e209d39SAndroid Build Coastguard Worker const char *srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
375*0e209d39SAndroid Build Coastguard Worker FILE *f = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"rbbitst.txt", "r");
376*0e209d39SAndroid Build Coastguard Worker
377*0e209d39SAndroid Build Coastguard Worker if (f != NULL) {
378*0e209d39SAndroid Build Coastguard Worker /* We're in icu/source/test/letest/ */
379*0e209d39SAndroid Build Coastguard Worker fclose(f);
380*0e209d39SAndroid Build Coastguard Worker } else {
381*0e209d39SAndroid Build Coastguard Worker /* We're in icu/source/test/letest/(Debug|Release) */
382*0e209d39SAndroid Build Coastguard Worker srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
383*0e209d39SAndroid Build Coastguard Worker }
384*0e209d39SAndroid Build Coastguard Worker #endif
385*0e209d39SAndroid Build Coastguard Worker
386*0e209d39SAndroid Build Coastguard Worker return srcDataDir;
387*0e209d39SAndroid Build Coastguard Worker }
388*0e209d39SAndroid Build Coastguard Worker
getPath(char buffer[2048],const char * filename)389*0e209d39SAndroid Build Coastguard Worker static const char *getPath(char buffer[2048], const char *filename) {
390*0e209d39SAndroid Build Coastguard Worker const char *testDataDirectory = getSourceTestData();
391*0e209d39SAndroid Build Coastguard Worker
392*0e209d39SAndroid Build Coastguard Worker strcpy(buffer, testDataDirectory);
393*0e209d39SAndroid Build Coastguard Worker strcat(buffer, filename);
394*0e209d39SAndroid Build Coastguard Worker
395*0e209d39SAndroid Build Coastguard Worker return buffer;
396*0e209d39SAndroid Build Coastguard Worker }
397*0e209d39SAndroid Build Coastguard Worker
openFont(const char * fontName,const char * checksum,const char * version,const char * testID)398*0e209d39SAndroid Build Coastguard Worker static le_font *openFont(const char *fontName, const char *checksum, const char *version, const char *testID)
399*0e209d39SAndroid Build Coastguard Worker {
400*0e209d39SAndroid Build Coastguard Worker char path[2048];
401*0e209d39SAndroid Build Coastguard Worker le_font *font;
402*0e209d39SAndroid Build Coastguard Worker LEErrorCode fontStatus = LE_NO_ERROR;
403*0e209d39SAndroid Build Coastguard Worker
404*0e209d39SAndroid Build Coastguard Worker if (fontName != NULL) {
405*0e209d39SAndroid Build Coastguard Worker font = le_portableFontOpen(getPath(path, fontName), 12, &fontStatus);
406*0e209d39SAndroid Build Coastguard Worker
407*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(fontStatus)) {
408*0e209d39SAndroid Build Coastguard Worker log_info("Test %s: can't open font %s - test skipped.\n", testID, fontName);
409*0e209d39SAndroid Build Coastguard Worker le_fontClose(font);
410*0e209d39SAndroid Build Coastguard Worker return NULL;
411*0e209d39SAndroid Build Coastguard Worker } else {
412*0e209d39SAndroid Build Coastguard Worker le_uint32 cksum = 0;
413*0e209d39SAndroid Build Coastguard Worker
414*0e209d39SAndroid Build Coastguard Worker sscanf(checksum, "%x", &cksum);
415*0e209d39SAndroid Build Coastguard Worker
416*0e209d39SAndroid Build Coastguard Worker checkFontVersion(font, version, cksum, testID);
417*0e209d39SAndroid Build Coastguard Worker }
418*0e209d39SAndroid Build Coastguard Worker } else {
419*0e209d39SAndroid Build Coastguard Worker font = le_simpleFontOpen(12, &fontStatus);
420*0e209d39SAndroid Build Coastguard Worker }
421*0e209d39SAndroid Build Coastguard Worker
422*0e209d39SAndroid Build Coastguard Worker return font;
423*0e209d39SAndroid Build Coastguard Worker }
424*0e209d39SAndroid Build Coastguard Worker
getRTL(const LEUnicode * text,le_int32 charCount)425*0e209d39SAndroid Build Coastguard Worker static le_bool getRTL(const LEUnicode *text, le_int32 charCount)
426*0e209d39SAndroid Build Coastguard Worker {
427*0e209d39SAndroid Build Coastguard Worker UBiDiLevel level;
428*0e209d39SAndroid Build Coastguard Worker le_int32 limit = -1;
429*0e209d39SAndroid Build Coastguard Worker UErrorCode status = U_ZERO_ERROR;
430*0e209d39SAndroid Build Coastguard Worker UBiDi *ubidi = ubidi_openSized(charCount, 0, &status);
431*0e209d39SAndroid Build Coastguard Worker
432*0e209d39SAndroid Build Coastguard Worker ubidi_setPara(ubidi, text, charCount, UBIDI_DEFAULT_LTR, NULL, &status);
433*0e209d39SAndroid Build Coastguard Worker
434*0e209d39SAndroid Build Coastguard Worker /* TODO: Should check that there's only a single logical run... */
435*0e209d39SAndroid Build Coastguard Worker ubidi_getLogicalRun(ubidi, 0, &limit, &level);
436*0e209d39SAndroid Build Coastguard Worker
437*0e209d39SAndroid Build Coastguard Worker ubidi_close(ubidi);
438*0e209d39SAndroid Build Coastguard Worker
439*0e209d39SAndroid Build Coastguard Worker return level & 1;
440*0e209d39SAndroid Build Coastguard Worker }
441*0e209d39SAndroid Build Coastguard Worker
doTestCase(const char * testID,const char * fontName,const char * fontVersion,const char * fontChecksum,le_int32 scriptCode,le_int32 languageCode,const LEUnicode * text,le_int32 charCount,TestResult * expected)442*0e209d39SAndroid Build Coastguard Worker static void doTestCase (const char *testID,
443*0e209d39SAndroid Build Coastguard Worker const char *fontName,
444*0e209d39SAndroid Build Coastguard Worker const char *fontVersion,
445*0e209d39SAndroid Build Coastguard Worker const char *fontChecksum,
446*0e209d39SAndroid Build Coastguard Worker le_int32 scriptCode,
447*0e209d39SAndroid Build Coastguard Worker le_int32 languageCode,
448*0e209d39SAndroid Build Coastguard Worker const LEUnicode *text,
449*0e209d39SAndroid Build Coastguard Worker le_int32 charCount,
450*0e209d39SAndroid Build Coastguard Worker TestResult *expected)
451*0e209d39SAndroid Build Coastguard Worker {
452*0e209d39SAndroid Build Coastguard Worker LEErrorCode status = LE_NO_ERROR;
453*0e209d39SAndroid Build Coastguard Worker le_engine *engine;
454*0e209d39SAndroid Build Coastguard Worker le_font *font = openFont(fontName, fontChecksum, fontVersion, testID);
455*0e209d39SAndroid Build Coastguard Worker le_int32 typoFlags = 3; /* kerning + ligatures */
456*0e209d39SAndroid Build Coastguard Worker TestResult actual;
457*0e209d39SAndroid Build Coastguard Worker
458*0e209d39SAndroid Build Coastguard Worker if (font == NULL) {
459*0e209d39SAndroid Build Coastguard Worker /* error message already printed. */
460*0e209d39SAndroid Build Coastguard Worker return;
461*0e209d39SAndroid Build Coastguard Worker }
462*0e209d39SAndroid Build Coastguard Worker
463*0e209d39SAndroid Build Coastguard Worker if (fontName == NULL) {
464*0e209d39SAndroid Build Coastguard Worker typoFlags |= 0x80000000L; /* use CharSubstitutionFilter... */
465*0e209d39SAndroid Build Coastguard Worker }
466*0e209d39SAndroid Build Coastguard Worker
467*0e209d39SAndroid Build Coastguard Worker engine = le_create(font, scriptCode, languageCode, typoFlags, &status);
468*0e209d39SAndroid Build Coastguard Worker
469*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
470*0e209d39SAndroid Build Coastguard Worker log_err("Test %s: could not create a LayoutEngine.\n", testID);
471*0e209d39SAndroid Build Coastguard Worker goto free_expected;
472*0e209d39SAndroid Build Coastguard Worker }
473*0e209d39SAndroid Build Coastguard Worker
474*0e209d39SAndroid Build Coastguard Worker actual.glyphCount = le_layoutChars(engine, text, 0, charCount, charCount, getRTL(text, charCount), 0, 0, &status);
475*0e209d39SAndroid Build Coastguard Worker
476*0e209d39SAndroid Build Coastguard Worker actual.glyphs = NEW_ARRAY(LEGlyphID, actual.glyphCount);
477*0e209d39SAndroid Build Coastguard Worker actual.indices = NEW_ARRAY(le_int32, actual.glyphCount);
478*0e209d39SAndroid Build Coastguard Worker actual.positions = NEW_ARRAY(float, actual.glyphCount * 2 + 2);
479*0e209d39SAndroid Build Coastguard Worker
480*0e209d39SAndroid Build Coastguard Worker le_getGlyphs(engine, actual.glyphs, &status);
481*0e209d39SAndroid Build Coastguard Worker le_getCharIndices(engine, actual.indices, &status);
482*0e209d39SAndroid Build Coastguard Worker le_getGlyphPositions(engine, actual.positions, &status);
483*0e209d39SAndroid Build Coastguard Worker
484*0e209d39SAndroid Build Coastguard Worker compareResults(testID, expected, &actual);
485*0e209d39SAndroid Build Coastguard Worker
486*0e209d39SAndroid Build Coastguard Worker DELETE_ARRAY(actual.positions);
487*0e209d39SAndroid Build Coastguard Worker DELETE_ARRAY(actual.indices);
488*0e209d39SAndroid Build Coastguard Worker DELETE_ARRAY(actual.glyphs);
489*0e209d39SAndroid Build Coastguard Worker
490*0e209d39SAndroid Build Coastguard Worker le_close(engine);
491*0e209d39SAndroid Build Coastguard Worker
492*0e209d39SAndroid Build Coastguard Worker free_expected:
493*0e209d39SAndroid Build Coastguard Worker le_fontClose(font);
494*0e209d39SAndroid Build Coastguard Worker }
495*0e209d39SAndroid Build Coastguard Worker
DataDrivenTest(void)496*0e209d39SAndroid Build Coastguard Worker static void U_CALLCONV DataDrivenTest(void)
497*0e209d39SAndroid Build Coastguard Worker {
498*0e209d39SAndroid Build Coastguard Worker char path[2048];
499*0e209d39SAndroid Build Coastguard Worker const char *testFilePath = getPath(path, "letest.xml");
500*0e209d39SAndroid Build Coastguard Worker
501*0e209d39SAndroid Build Coastguard Worker readTestFile(testFilePath, doTestCase);
502*0e209d39SAndroid Build Coastguard Worker }
503*0e209d39SAndroid Build Coastguard Worker
504*0e209d39SAndroid Build Coastguard Worker /*
505*0e209d39SAndroid Build Coastguard Worker * From ticket:5923:
506*0e209d39SAndroid Build Coastguard Worker *
507*0e209d39SAndroid Build Coastguard Worker * Build a paragraph that contains a mixture of left to right and right to left text.
508*0e209d39SAndroid Build Coastguard Worker * Break it into multiple lines and make sure that the glyphToCharMap for run in each
509*0e209d39SAndroid Build Coastguard Worker * line is correct.
510*0e209d39SAndroid Build Coastguard Worker *
511*0e209d39SAndroid Build Coastguard Worker * Note: it might be a good idea to also check the glyphs and positions for each run,
512*0e209d39SAndroid Build Coastguard Worker * that we get the expected number of runs per line and that the line breaks are where
513*0e209d39SAndroid Build Coastguard Worker * we expect them to be. Really, it would be a good idea to make a whole test suite
514*0e209d39SAndroid Build Coastguard Worker * for pl_paragraph.
515*0e209d39SAndroid Build Coastguard Worker */
GlyphToCharTest(void)516*0e209d39SAndroid Build Coastguard Worker static void U_CALLCONV GlyphToCharTest(void)
517*0e209d39SAndroid Build Coastguard Worker {
518*0e209d39SAndroid Build Coastguard Worker #if !UCONFIG_NO_BREAK_ITERATION
519*0e209d39SAndroid Build Coastguard Worker LEErrorCode status = LE_NO_ERROR;
520*0e209d39SAndroid Build Coastguard Worker le_font *font;
521*0e209d39SAndroid Build Coastguard Worker pl_fontRuns *fontRuns;
522*0e209d39SAndroid Build Coastguard Worker pl_paragraph *paragraph;
523*0e209d39SAndroid Build Coastguard Worker const pl_line *line;
524*0e209d39SAndroid Build Coastguard Worker /*
525*0e209d39SAndroid Build Coastguard Worker * This is the same text that's in <icu>/source/samples/layout/Sample.txt
526*0e209d39SAndroid Build Coastguard Worker */
527*0e209d39SAndroid Build Coastguard Worker LEUnicode chars[] = {
528*0e209d39SAndroid Build Coastguard Worker /*BOM*/ 0x0054, 0x0068, 0x0065, 0x0020, 0x004c, 0x0061, 0x0079,
529*0e209d39SAndroid Build Coastguard Worker 0x006f, 0x0075, 0x0074, 0x0045, 0x006e, 0x0067, 0x0069, 0x006e,
530*0e209d39SAndroid Build Coastguard Worker 0x0065, 0x0020, 0x0064, 0x006f, 0x0065, 0x0073, 0x0020, 0x0061,
531*0e209d39SAndroid Build Coastguard Worker 0x006c, 0x006c, 0x0020, 0x0074, 0x0068, 0x0065, 0x0020, 0x0077,
532*0e209d39SAndroid Build Coastguard Worker 0x006f, 0x0072, 0x006b, 0x0020, 0x006e, 0x0065, 0x0063, 0x0065,
533*0e209d39SAndroid Build Coastguard Worker 0x0073, 0x0073, 0x0061, 0x0072, 0x0079, 0x0020, 0x0074, 0x006f,
534*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0064, 0x0069, 0x0073, 0x0070, 0x006c, 0x0061, 0x0079,
535*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0055, 0x006e, 0x0069, 0x0063, 0x006f, 0x0064, 0x0065,
536*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x0020, 0x0077, 0x0072,
537*0e209d39SAndroid Build Coastguard Worker 0x0069, 0x0074, 0x0074, 0x0065, 0x006e, 0x0020, 0x0069, 0x006e,
538*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x006c, 0x0061, 0x006e, 0x0067, 0x0075, 0x0061, 0x0067,
539*0e209d39SAndroid Build Coastguard Worker 0x0065, 0x0073, 0x0020, 0x0077, 0x0069, 0x0074, 0x0068, 0x0020,
540*0e209d39SAndroid Build Coastguard Worker 0x0063, 0x006f, 0x006d, 0x0070, 0x006c, 0x0065, 0x0078, 0x0020,
541*0e209d39SAndroid Build Coastguard Worker 0x0077, 0x0072, 0x0069, 0x0074, 0x0069, 0x006e, 0x0067, 0x0020,
542*0e209d39SAndroid Build Coastguard Worker 0x0073, 0x0079, 0x0073, 0x0074, 0x0065, 0x006d, 0x0073, 0x0020,
543*0e209d39SAndroid Build Coastguard Worker 0x0073, 0x0075, 0x0063, 0x0068, 0x0020, 0x0061, 0x0073, 0x0020,
544*0e209d39SAndroid Build Coastguard Worker 0x0048, 0x0069, 0x006e, 0x0064, 0x0069, 0x0020, 0x0028, 0x0939,
545*0e209d39SAndroid Build Coastguard Worker 0x093f, 0x0928, 0x094d, 0x0926, 0x0940, 0x0029, 0x0020, 0x0054,
546*0e209d39SAndroid Build Coastguard Worker 0x0068, 0x0061, 0x0069, 0x0020, 0x0028, 0x0e44, 0x0e17, 0x0e22,
547*0e209d39SAndroid Build Coastguard Worker 0x0029, 0x0020, 0x0061, 0x006e, 0x0064, 0x0020, 0x0041, 0x0072,
548*0e209d39SAndroid Build Coastguard Worker 0x0061, 0x0062, 0x0069, 0x0063, 0x0020, 0x0028, 0x0627, 0x0644,
549*0e209d39SAndroid Build Coastguard Worker 0x0639, 0x0631, 0x0628, 0x064a, 0x0629, 0x0029, 0x002e, 0x0020,
550*0e209d39SAndroid Build Coastguard Worker 0x0048, 0x0065, 0x0072, 0x0065, 0x0027, 0x0073, 0x0020, 0x0061,
551*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0073, 0x0061, 0x006d, 0x0070, 0x006c, 0x0065, 0x0020,
552*0e209d39SAndroid Build Coastguard Worker 0x006f, 0x0066, 0x0020, 0x0073, 0x006f, 0x006d, 0x0065, 0x0020,
553*0e209d39SAndroid Build Coastguard Worker 0x0074, 0x0065, 0x0078, 0x0074, 0x0020, 0x0077, 0x0072, 0x0069,
554*0e209d39SAndroid Build Coastguard Worker 0x0074, 0x0074, 0x0065, 0x006e, 0x0020, 0x0069, 0x006e, 0x0020,
555*0e209d39SAndroid Build Coastguard Worker 0x0053, 0x0061, 0x006e, 0x0073, 0x006b, 0x0072, 0x0069, 0x0074,
556*0e209d39SAndroid Build Coastguard Worker 0x003a, 0x0020, 0x0936, 0x094d, 0x0930, 0x0940, 0x092e, 0x0926,
557*0e209d39SAndroid Build Coastguard Worker 0x094d, 0x0020, 0x092d, 0x0917, 0x0935, 0x0926, 0x094d, 0x0917,
558*0e209d39SAndroid Build Coastguard Worker 0x0940, 0x0924, 0x093e, 0x0020, 0x0905, 0x0927, 0x094d, 0x092f,
559*0e209d39SAndroid Build Coastguard Worker 0x093e, 0x092f, 0x0020, 0x0905, 0x0930, 0x094d, 0x091c, 0x0941,
560*0e209d39SAndroid Build Coastguard Worker 0x0928, 0x0020, 0x0935, 0x093f, 0x0937, 0x093e, 0x0926, 0x0020,
561*0e209d39SAndroid Build Coastguard Worker 0x092f, 0x094b, 0x0917, 0x0020, 0x0927, 0x0943, 0x0924, 0x0930,
562*0e209d39SAndroid Build Coastguard Worker 0x093e, 0x0937, 0x094d, 0x091f, 0x094d, 0x0930, 0x0020, 0x0909,
563*0e209d39SAndroid Build Coastguard Worker 0x0935, 0x093e, 0x091a, 0x0964, 0x0020, 0x0927, 0x0930, 0x094d,
564*0e209d39SAndroid Build Coastguard Worker 0x092e, 0x0915, 0x094d, 0x0937, 0x0947, 0x0924, 0x094d, 0x0930,
565*0e209d39SAndroid Build Coastguard Worker 0x0947, 0x0020, 0x0915, 0x0941, 0x0930, 0x0941, 0x0915, 0x094d,
566*0e209d39SAndroid Build Coastguard Worker 0x0937, 0x0947, 0x0924, 0x094d, 0x0930, 0x0947, 0x0020, 0x0938,
567*0e209d39SAndroid Build Coastguard Worker 0x092e, 0x0935, 0x0947, 0x0924, 0x093e, 0x0020, 0x092f, 0x0941,
568*0e209d39SAndroid Build Coastguard Worker 0x092f, 0x0941, 0x0924, 0x094d, 0x0938, 0x0935, 0x0903, 0x0020,
569*0e209d39SAndroid Build Coastguard Worker 0x092e, 0x093e, 0x092e, 0x0915, 0x093e, 0x0903, 0x0020, 0x092a,
570*0e209d39SAndroid Build Coastguard Worker 0x093e, 0x0923, 0x094d, 0x0921, 0x0935, 0x093e, 0x0936, 0x094d,
571*0e209d39SAndroid Build Coastguard Worker 0x091a, 0x0948, 0x0935, 0x0020, 0x0915, 0x093f, 0x092e, 0x0915,
572*0e209d39SAndroid Build Coastguard Worker 0x0941, 0x0930, 0x094d, 0x0935, 0x0924, 0x0020, 0x0938, 0x0902,
573*0e209d39SAndroid Build Coastguard Worker 0x091c, 0x092f, 0x0020, 0x0048, 0x0065, 0x0072, 0x0065, 0x0027,
574*0e209d39SAndroid Build Coastguard Worker 0x0073, 0x0020, 0x0061, 0x0020, 0x0073, 0x0061, 0x006d, 0x0070,
575*0e209d39SAndroid Build Coastguard Worker 0x006c, 0x0065, 0x0020, 0x006f, 0x0066, 0x0020, 0x0073, 0x006f,
576*0e209d39SAndroid Build Coastguard Worker 0x006d, 0x0065, 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x0020,
577*0e209d39SAndroid Build Coastguard Worker 0x0077, 0x0072, 0x0069, 0x0074, 0x0074, 0x0065, 0x006e, 0x0020,
578*0e209d39SAndroid Build Coastguard Worker 0x0069, 0x006e, 0x0020, 0x0041, 0x0072, 0x0061, 0x0062, 0x0069,
579*0e209d39SAndroid Build Coastguard Worker 0x0063, 0x003a, 0x0020, 0x0623, 0x0633, 0x0627, 0x0633, 0x064b,
580*0e209d39SAndroid Build Coastguard Worker 0x0627, 0x060c, 0x0020, 0x062a, 0x062a, 0x0639, 0x0627, 0x0645,
581*0e209d39SAndroid Build Coastguard Worker 0x0644, 0x0020, 0x0627, 0x0644, 0x062d, 0x0648, 0x0627, 0x0633,
582*0e209d39SAndroid Build Coastguard Worker 0x064a, 0x0628, 0x0020, 0x0641, 0x0642, 0x0637, 0x0020, 0x0645,
583*0e209d39SAndroid Build Coastguard Worker 0x0639, 0x0020, 0x0627, 0x0644, 0x0623, 0x0631, 0x0642, 0x0627,
584*0e209d39SAndroid Build Coastguard Worker 0x0645, 0x060c, 0x0020, 0x0648, 0x062a, 0x0642, 0x0648, 0x0645,
585*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0628, 0x062a, 0x062e, 0x0632, 0x064a, 0x0646, 0x0020,
586*0e209d39SAndroid Build Coastguard Worker 0x0627, 0x0644, 0x0623, 0x062d, 0x0631, 0x0641, 0x0020, 0x0648,
587*0e209d39SAndroid Build Coastguard Worker 0x0627, 0x0644, 0x0645, 0x062d, 0x0627, 0x0631, 0x0641, 0x0020,
588*0e209d39SAndroid Build Coastguard Worker 0x0627, 0x0644, 0x0623, 0x062e, 0x0631, 0x0649, 0x0020, 0x0628,
589*0e209d39SAndroid Build Coastguard Worker 0x0639, 0x062f, 0x0020, 0x0623, 0x0646, 0x0020, 0x062a, 0x064f,
590*0e209d39SAndroid Build Coastguard Worker 0x0639, 0x0637, 0x064a, 0x0020, 0x0631, 0x0642, 0x0645, 0x0627,
591*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0645, 0x0639, 0x064a, 0x0646, 0x0627, 0x0020, 0x0644,
592*0e209d39SAndroid Build Coastguard Worker 0x0643, 0x0644, 0x0020, 0x0648, 0x0627, 0x062d, 0x062f, 0x0020,
593*0e209d39SAndroid Build Coastguard Worker 0x0645, 0x0646, 0x0647, 0x0627, 0x002e, 0x0020, 0x0648, 0x0642,
594*0e209d39SAndroid Build Coastguard Worker 0x0628, 0x0644, 0x0020, 0x0627, 0x062e, 0x062a, 0x0631, 0x0627,
595*0e209d39SAndroid Build Coastguard Worker 0x0639, 0x0020, 0x0022, 0x064a, 0x0648, 0x0646, 0x0650, 0x0643,
596*0e209d39SAndroid Build Coastguard Worker 0x0648, 0x062f, 0x0022, 0x060c, 0x0020, 0x0643, 0x0627, 0x0646,
597*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0647, 0x0646, 0x0627, 0x0643, 0x0020, 0x0645, 0x0626,
598*0e209d39SAndroid Build Coastguard Worker 0x0627, 0x062a, 0x0020, 0x0627, 0x0644, 0x0623, 0x0646, 0x0638,
599*0e209d39SAndroid Build Coastguard Worker 0x0645, 0x0629, 0x0020, 0x0644, 0x0644, 0x062a, 0x0634, 0x0641,
600*0e209d39SAndroid Build Coastguard Worker 0x064a, 0x0631, 0x0020, 0x0648, 0x062a, 0x062e, 0x0635, 0x064a,
601*0e209d39SAndroid Build Coastguard Worker 0x0635, 0x0020, 0x0647, 0x0630, 0x0647, 0x0020, 0x0627, 0x0644,
602*0e209d39SAndroid Build Coastguard Worker 0x0623, 0x0631, 0x0642, 0x0627, 0x0645, 0x0020, 0x0644, 0x0644,
603*0e209d39SAndroid Build Coastguard Worker 0x0645, 0x062d, 0x0627, 0x0631, 0x0641, 0x060c, 0x0020, 0x0648,
604*0e209d39SAndroid Build Coastguard Worker 0x0644, 0x0645, 0x0020, 0x064a, 0x0648, 0x062c, 0x062f, 0x0020,
605*0e209d39SAndroid Build Coastguard Worker 0x0646, 0x0638, 0x0627, 0x0645, 0x0020, 0x062a, 0x0634, 0x0641,
606*0e209d39SAndroid Build Coastguard Worker 0x064a, 0x0631, 0x0020, 0x0648, 0x0627, 0x062d, 0x062f, 0x0020,
607*0e209d39SAndroid Build Coastguard Worker 0x064a, 0x062d, 0x062a, 0x0648, 0x064a, 0x0020, 0x0639, 0x0644,
608*0e209d39SAndroid Build Coastguard Worker 0x0649, 0x0020, 0x062c, 0x0645, 0x064a, 0x0639, 0x0020, 0x0627,
609*0e209d39SAndroid Build Coastguard Worker 0x0644, 0x0645, 0x062d, 0x0627, 0x0631, 0x0641, 0x0020, 0x0627,
610*0e209d39SAndroid Build Coastguard Worker 0x0644, 0x0636, 0x0631, 0x0648, 0x0631, 0x064a, 0x0629, 0x0020,
611*0e209d39SAndroid Build Coastguard Worker 0x0061, 0x006e, 0x0064, 0x0020, 0x0068, 0x0065, 0x0072, 0x0065,
612*0e209d39SAndroid Build Coastguard Worker 0x0027, 0x0073, 0x0020, 0x0061, 0x0020, 0x0073, 0x0061, 0x006d,
613*0e209d39SAndroid Build Coastguard Worker 0x0070, 0x006c, 0x0065, 0x0020, 0x006f, 0x0066, 0x0020, 0x0073,
614*0e209d39SAndroid Build Coastguard Worker 0x006f, 0x006d, 0x0065, 0x0020, 0x0074, 0x0065, 0x0078, 0x0074,
615*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0077, 0x0072, 0x0069, 0x0074, 0x0074, 0x0065, 0x006e,
616*0e209d39SAndroid Build Coastguard Worker 0x0020, 0x0069, 0x006e, 0x0020, 0x0054, 0x0068, 0x0061, 0x0069,
617*0e209d39SAndroid Build Coastguard Worker 0x003a, 0x0020, 0x0e1a, 0x0e17, 0x0e17, 0x0e35, 0x0e48, 0x0e51,
618*0e209d39SAndroid Build Coastguard Worker 0x0e1e, 0x0e32, 0x0e22, 0x0e38, 0x0e44, 0x0e0b, 0x0e42, 0x0e04,
619*0e209d39SAndroid Build Coastguard Worker 0x0e25, 0x0e19, 0x0e42, 0x0e14, 0x0e42, 0x0e23, 0x0e18, 0x0e35,
620*0e209d39SAndroid Build Coastguard Worker 0x0e2d, 0x0e32, 0x0e28, 0x0e31, 0x0e22, 0x0e2d, 0x0e22, 0x0e39,
621*0e209d39SAndroid Build Coastguard Worker 0x0e48, 0x0e17, 0x0e48, 0x0e32, 0x0e21, 0x0e01, 0x0e25, 0x0e32,
622*0e209d39SAndroid Build Coastguard Worker 0x0e07, 0x0e17, 0x0e38, 0x0e48, 0x0e07, 0x0e43, 0x0e2b, 0x0e0d,
623*0e209d39SAndroid Build Coastguard Worker 0x0e48, 0x0e43, 0x0e19, 0x0e41, 0x0e04, 0x0e19, 0x0e0b, 0x0e31,
624*0e209d39SAndroid Build Coastguard Worker 0x0e2a, 0x0e01, 0x0e31, 0x0e1a, 0x0e25, 0x0e38, 0x0e07, 0x0e40,
625*0e209d39SAndroid Build Coastguard Worker 0x0e2e, 0x0e19, 0x0e23, 0x0e35, 0x0e0a, 0x0e32, 0x0e27, 0x0e44,
626*0e209d39SAndroid Build Coastguard Worker 0x0e23, 0x0e48, 0x0e41, 0x0e25, 0x0e30, 0x0e1b, 0x0e49, 0x0e32,
627*0e209d39SAndroid Build Coastguard Worker 0x0e40, 0x0e2d, 0x0e47, 0x0e21, 0x0e20, 0x0e23, 0x0e23, 0x0e22,
628*0e209d39SAndroid Build Coastguard Worker 0x0e32, 0x0e0a, 0x0e32, 0x0e27, 0x0e44, 0x0e23, 0x0e48, 0x0e1a,
629*0e209d39SAndroid Build Coastguard Worker 0x0e49, 0x0e32, 0x0e19, 0x0e02, 0x0e2d, 0x0e07, 0x0e1e, 0x0e27,
630*0e209d39SAndroid Build Coastguard Worker 0x0e01, 0x0e40, 0x0e02, 0x0e32, 0x0e2b, 0x0e25, 0x0e31, 0x0e07,
631*0e209d39SAndroid Build Coastguard Worker 0x0e40, 0x0e25, 0x0e47, 0x0e01, 0x0e40, 0x0e1e, 0x0e23, 0x0e32,
632*0e209d39SAndroid Build Coastguard Worker 0x0e30, 0x0e44, 0x0e21, 0x0e49, 0x0e2a, 0x0e23, 0x0e49, 0x0e32,
633*0e209d39SAndroid Build Coastguard Worker 0x0e07, 0x0e1a, 0x0e49, 0x0e32, 0x0e19, 0x0e15, 0x0e49, 0x0e2d,
634*0e209d39SAndroid Build Coastguard Worker 0x0e07, 0x0e02, 0x0e19, 0x0e21, 0x0e32, 0x0e14, 0x0e49, 0x0e27,
635*0e209d39SAndroid Build Coastguard Worker 0x0e22, 0x0e40, 0x0e01, 0x0e27, 0x0e35, 0x0e22, 0x0e19, 0x0e40,
636*0e209d39SAndroid Build Coastguard Worker 0x0e1b, 0x0e47, 0x0e19, 0x0e23, 0x0e30, 0x0e22, 0x0e30, 0x0e17,
637*0e209d39SAndroid Build Coastguard Worker 0x0e32, 0x0e07, 0x0e2b, 0x0e25, 0x0e32, 0x0e22, 0x0e44, 0x0e21,
638*0e209d39SAndroid Build Coastguard Worker 0x0e25, 0x0e4c
639*0e209d39SAndroid Build Coastguard Worker };
640*0e209d39SAndroid Build Coastguard Worker le_int32 charCount = LE_ARRAY_SIZE(chars);
641*0e209d39SAndroid Build Coastguard Worker le_int32 charIndex = 0, lineNumber = 1;
642*0e209d39SAndroid Build Coastguard Worker le_int32 run, i;
643*0e209d39SAndroid Build Coastguard Worker const float lineWidth = 600;
644*0e209d39SAndroid Build Coastguard Worker
645*0e209d39SAndroid Build Coastguard Worker font = le_simpleFontOpen(12, &status);
646*0e209d39SAndroid Build Coastguard Worker
647*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
648*0e209d39SAndroid Build Coastguard Worker log_err("le_simpleFontOpen(12, &status) failed");
649*0e209d39SAndroid Build Coastguard Worker goto finish;
650*0e209d39SAndroid Build Coastguard Worker }
651*0e209d39SAndroid Build Coastguard Worker
652*0e209d39SAndroid Build Coastguard Worker fontRuns = pl_openEmptyFontRuns(0);
653*0e209d39SAndroid Build Coastguard Worker pl_addFontRun(fontRuns, font, charCount);
654*0e209d39SAndroid Build Coastguard Worker
655*0e209d39SAndroid Build Coastguard Worker paragraph = pl_create(chars, charCount, fontRuns, NULL, NULL, NULL, 0, false, &status);
656*0e209d39SAndroid Build Coastguard Worker
657*0e209d39SAndroid Build Coastguard Worker pl_closeFontRuns(fontRuns);
658*0e209d39SAndroid Build Coastguard Worker
659*0e209d39SAndroid Build Coastguard Worker if (LE_FAILURE(status)) {
660*0e209d39SAndroid Build Coastguard Worker log_err("pl_create failed.");
661*0e209d39SAndroid Build Coastguard Worker goto close_font;
662*0e209d39SAndroid Build Coastguard Worker }
663*0e209d39SAndroid Build Coastguard Worker
664*0e209d39SAndroid Build Coastguard Worker pl_reflow(paragraph);
665*0e209d39SAndroid Build Coastguard Worker while ((line = pl_nextLine(paragraph, lineWidth)) != NULL) {
666*0e209d39SAndroid Build Coastguard Worker le_int32 runCount = pl_countLineRuns(line);
667*0e209d39SAndroid Build Coastguard Worker
668*0e209d39SAndroid Build Coastguard Worker for(run = 0; run < runCount; run += 1) {
669*0e209d39SAndroid Build Coastguard Worker const pl_visualRun *visualRun = pl_getLineVisualRun(line, run);
670*0e209d39SAndroid Build Coastguard Worker const le_int32 glyphCount = pl_getVisualRunGlyphCount(visualRun);
671*0e209d39SAndroid Build Coastguard Worker const le_int32 *glyphToCharMap = pl_getVisualRunGlyphToCharMap(visualRun);
672*0e209d39SAndroid Build Coastguard Worker
673*0e209d39SAndroid Build Coastguard Worker if (pl_getVisualRunDirection(visualRun) == UBIDI_RTL) {
674*0e209d39SAndroid Build Coastguard Worker /*
675*0e209d39SAndroid Build Coastguard Worker * For a right to left run, make sure that the character indices
676*0e209d39SAndroid Build Coastguard Worker * increase from the right most glyph to the left most glyph. If
677*0e209d39SAndroid Build Coastguard Worker * there are any one to many glyph substitutions, we might get several
678*0e209d39SAndroid Build Coastguard Worker * glyphs in a row with the same character index.
679*0e209d39SAndroid Build Coastguard Worker */
680*0e209d39SAndroid Build Coastguard Worker for(i = glyphCount - 1; i >= 0; i -= 1) {
681*0e209d39SAndroid Build Coastguard Worker le_int32 ix = glyphToCharMap[i];
682*0e209d39SAndroid Build Coastguard Worker
683*0e209d39SAndroid Build Coastguard Worker if (ix != charIndex) {
684*0e209d39SAndroid Build Coastguard Worker if (ix != charIndex - 1) {
685*0e209d39SAndroid Build Coastguard Worker log_err("Bad glyph to char index for glyph %d on line %d: expected %d, got %d\n",
686*0e209d39SAndroid Build Coastguard Worker i, lineNumber, charIndex, ix);
687*0e209d39SAndroid Build Coastguard Worker goto close_paragraph; /* once there's one error, we can't count on anything else... */
688*0e209d39SAndroid Build Coastguard Worker }
689*0e209d39SAndroid Build Coastguard Worker } else {
690*0e209d39SAndroid Build Coastguard Worker charIndex += 1;
691*0e209d39SAndroid Build Coastguard Worker }
692*0e209d39SAndroid Build Coastguard Worker }
693*0e209d39SAndroid Build Coastguard Worker } else {
694*0e209d39SAndroid Build Coastguard Worker /*
695*0e209d39SAndroid Build Coastguard Worker * We can't just check the order of the character indices
696*0e209d39SAndroid Build Coastguard Worker * for left to right runs because Indic text might have been
697*0e209d39SAndroid Build Coastguard Worker * reordered. What we can do is find the minimum and maximum
698*0e209d39SAndroid Build Coastguard Worker * character indices in the run and make sure that the minimum
699*0e209d39SAndroid Build Coastguard Worker * is equal to charIndex and then advance charIndex to the maximum.
700*0e209d39SAndroid Build Coastguard Worker */
701*0e209d39SAndroid Build Coastguard Worker le_int32 minIndex = 0x7FFFFFFF, maxIndex = -1;
702*0e209d39SAndroid Build Coastguard Worker
703*0e209d39SAndroid Build Coastguard Worker for(i = 0; i < glyphCount; i += 1) {
704*0e209d39SAndroid Build Coastguard Worker le_int32 ix = glyphToCharMap[i];
705*0e209d39SAndroid Build Coastguard Worker
706*0e209d39SAndroid Build Coastguard Worker if (ix > maxIndex) {
707*0e209d39SAndroid Build Coastguard Worker maxIndex = ix;
708*0e209d39SAndroid Build Coastguard Worker }
709*0e209d39SAndroid Build Coastguard Worker
710*0e209d39SAndroid Build Coastguard Worker if (ix < minIndex) {
711*0e209d39SAndroid Build Coastguard Worker minIndex = ix;
712*0e209d39SAndroid Build Coastguard Worker }
713*0e209d39SAndroid Build Coastguard Worker }
714*0e209d39SAndroid Build Coastguard Worker
715*0e209d39SAndroid Build Coastguard Worker if (minIndex != charIndex) {
716*0e209d39SAndroid Build Coastguard Worker log_err("Bad minIndex for run %d on line %d: expected %d, got %d\n",
717*0e209d39SAndroid Build Coastguard Worker run, lineNumber, charIndex, minIndex);
718*0e209d39SAndroid Build Coastguard Worker goto close_paragraph; /* once there's one error, we can't count on anything else... */
719*0e209d39SAndroid Build Coastguard Worker }
720*0e209d39SAndroid Build Coastguard Worker
721*0e209d39SAndroid Build Coastguard Worker charIndex = maxIndex + 1;
722*0e209d39SAndroid Build Coastguard Worker }
723*0e209d39SAndroid Build Coastguard Worker }
724*0e209d39SAndroid Build Coastguard Worker
725*0e209d39SAndroid Build Coastguard Worker lineNumber += 1;
726*0e209d39SAndroid Build Coastguard Worker }
727*0e209d39SAndroid Build Coastguard Worker
728*0e209d39SAndroid Build Coastguard Worker close_paragraph:
729*0e209d39SAndroid Build Coastguard Worker pl_close(paragraph);
730*0e209d39SAndroid Build Coastguard Worker
731*0e209d39SAndroid Build Coastguard Worker close_font:
732*0e209d39SAndroid Build Coastguard Worker le_fontClose(font);
733*0e209d39SAndroid Build Coastguard Worker
734*0e209d39SAndroid Build Coastguard Worker finish:
735*0e209d39SAndroid Build Coastguard Worker return;
736*0e209d39SAndroid Build Coastguard Worker #endif
737*0e209d39SAndroid Build Coastguard Worker }
738*0e209d39SAndroid Build Coastguard Worker
addCTests(TestNode ** root)739*0e209d39SAndroid Build Coastguard Worker U_CFUNC void addCTests(TestNode **root)
740*0e209d39SAndroid Build Coastguard Worker {
741*0e209d39SAndroid Build Coastguard Worker addTest(root, &ParamTest, "c_api/ParameterTest");
742*0e209d39SAndroid Build Coastguard Worker addTest(root, &FactoryTest, "c_api/FactoryTest");
743*0e209d39SAndroid Build Coastguard Worker addTest(root, &AccessTest, "c_layout/AccessTest");
744*0e209d39SAndroid Build Coastguard Worker addTest(root, &DataDrivenTest, "c_layout/DataDrivenTest");
745*0e209d39SAndroid Build Coastguard Worker addTest(root, &GlyphToCharTest, "c_paragraph/GlyphToCharTest");
746*0e209d39SAndroid Build Coastguard Worker }
747*0e209d39SAndroid Build Coastguard Worker
748*0e209d39SAndroid Build Coastguard Worker
749*0e209d39SAndroid Build Coastguard Worker #endif
750