1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************************* 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 4fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Copyright (C) 1999-2014, International Business Machines 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Corporation and others. All Rights Reserved. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************************* 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * file name: letest.cpp 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * created on: 11/06/2000 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * created by: Eric R. Mader 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uclean.h" 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uchar.h" 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/unistr.h" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uscript.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ctest.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/LETypes.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/LEScripts.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/LayoutEngine.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/ParagraphLayout.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/RunArrays.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "PortableFontInstance.h" 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "SimpleFontInstance.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "letsutil.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "letest.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "xmlparser.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h" // for uprv_getUTCtime() 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdlib.h> 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <string.h> 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_USE 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CH_COMMA 0x002C 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV ScriptTest(void) 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 4985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if ((int)scriptCodeCount != (int)USCRIPT_CODE_LIMIT) { 5085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho log_err("ScriptCodes::scriptCodeCount = %d, but UScriptCode::USCRIPT_CODE_LIMIT = %d\n", scriptCodeCount, USCRIPT_CODE_LIMIT); 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV ParamTest(void) 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode status = LE_NO_ERROR; 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleFontInstance *font = new SimpleFontInstance(12, status); 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LayoutEngine *engine = LayoutEngine::layoutEngineFactory(font, arabScriptCode, -1, status); 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEGlyphID *glyphs = NULL; 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *indices = NULL; 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float *positions = NULL; 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount = 0; 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = engine->getGlyphCount(); 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (glyphCount != 0) { 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphCount() on an empty layout returned %d.\n", glyphCount); 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphs = NEW_ARRAY(LEGlyphID, glyphCount + 10); 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indices = NEW_ARRAY(le_int32, glyphCount + 10); 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru positions = NEW_ARRAY(float, glyphCount + 10); 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(NULL, status); 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphs(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n"); 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(glyphs, status); 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_NO_LAYOUT_ERROR) { 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphs(glyphs, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n"); 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(NULL, 0xFF000000L, status); 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphs(NULL, 0xFF000000L, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n"); 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(glyphs, 0xFF000000L, status); 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_NO_LAYOUT_ERROR) { 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphs(glyphs, 0xFF000000L, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n"); 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(NULL, status); 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getCharIndices(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n"); 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(indices, status); 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_NO_LAYOUT_ERROR) { 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getCharIndices(indices, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n"); 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(NULL, 1024, status); 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getCharIndices(NULL, 1024, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n"); 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(indices, 1024, status); 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_NO_LAYOUT_ERROR) { 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getCharIndices(indices, 1024, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n"); 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPositions(NULL, status); 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphPositions(NULL, status) did not return LE_ILLEGAL_ARGUMENT_ERROR.\n"); 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPositions(positions, status); 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_NO_LAYOUT_ERROR) { 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphPositions(positions, status) on an empty layout did not return LE_NO_LAYOUT_ERROR.\n"); 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(positions); 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(indices); 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(glyphs); 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = engine->layoutChars(NULL, 0, 0, 0, FALSE, 0.0, 0.0, status); 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling layoutChars(NULL, 0, 0, 0, FALSE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n"); 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEUnicode chars[] = { 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, 0x0020, // "English " 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0645, 0x0627, 0x0646, 0x062A, 0x0648, 0x0634, // MEM ALIF KAF NOON TEH WAW SHEEN 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x02E // " text." 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = engine->layoutChars(chars, -1, 6, 20, TRUE, 0.0, 0.0, status); 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling layoutChars(chars, -1, 6, 20, TRUE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n"); 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = engine->layoutChars(chars, 8, -1, 20, TRUE, 0.0, 0.0, status); 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling layoutChars(chars, 8, -1, 20, TRUE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n"); 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = engine->layoutChars(chars, 8, 6, -1, TRUE, 0.0, 0.0, status); 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling layoutChars((chars, 8, 6, -1, TRUE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n"); 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = engine->layoutChars(chars, 8, 6, 10, TRUE, 0.0, 0.0, status); 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_ILLEGAL_ARGUMENT_ERROR) { 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling layoutChars(chars, 8, 6, 10, TRUE, 0.0, 0.0, status) did not fail w/ LE_ILLEGAL_ARGUMENT_ERROR.\n"); 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float x = 0.0, y = 0.0; 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = engine->layoutChars(chars, 8, 6, 20, TRUE, 0.0, 0.0, status); 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling layoutChars(chars, 8, 6, 20, TRUE, 0.0, 0.0, status) failed.\n"); 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto bail; 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPosition(-1, x, y, status); 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_INDEX_OUT_OF_BOUNDS_ERROR) { 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphPosition(-1, x, y, status) did not fail w/ LE_INDEX_OUT_OF_BOUNDS_ERROR.\n"); 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPosition(glyphCount + 1, x, y, status); 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status != LE_INDEX_OUT_OF_BOUNDS_ERROR) { 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Calling getGlyphPosition(glyphCount + 1, x, y, status) did not fail w/ LE_INDEX_OUT_OF_BOUNDS_ERROR.\n"); 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubail: 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete engine; 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete font; 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV FactoryTest(void) 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode status = LE_NO_ERROR; 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleFontInstance *font = new SimpleFontInstance(12, status); 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LayoutEngine *engine = NULL; 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(le_int32 scriptCode = 0; scriptCode < scriptCodeCount; scriptCode += 1) { 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine = LayoutEngine::layoutEngineFactory(font, scriptCode, -1, status); 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Could not create a LayoutEngine for script \'%s\'.\n", uscript_getShortName((UScriptCode)scriptCode)); 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete engine; 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete font; 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV AccessTest(void) 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode status = LE_NO_ERROR; 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleFontInstance *font = new SimpleFontInstance(12, status); 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LayoutEngine *engine = LayoutEngine::layoutEngineFactory(font, arabScriptCode, -1, status); 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount; 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEGlyphID glyphs[6], extraBitGlyphs[6];; 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 biasedIndices[6], indices[6], glyph; 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float positions[6 * 2 + 2]; 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEUnicode chars[] = { 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, 0x0020, // "English " 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0645, 0x0627, 0x0646, 0x062A, 0x0648, 0x0634, // MEM ALIF KAF NOON TEH WAW SHEEN 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x02E // " text." 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Could not create LayoutEngine.\n"); 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto bail; 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = engine->layoutChars(chars, 8, 6, 20, TRUE, 0.0, 0.0, status); 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status) || glyphCount != 6) { 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("layoutChars(chars, 8, 6, 20, TRUE, 0.0, 0.0, status) failed.\n"); 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto bail; 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(glyphs, status); 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(indices, status); 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPositions(positions, status); 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Could not get glyph, indices and position arrays.\n"); 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto bail; 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(extraBitGlyphs, 0xFF000000L, status); 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("getGlyphs(extraBitGlyphs, 0xFF000000L, status); failed.\n"); 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(glyph = 0; glyph < glyphCount; glyph += 1) { 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (extraBitGlyphs[glyph] != (glyphs[glyph] | 0xFF000000L)) { 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("extraBigGlyphs[%d] != glyphs[%d] | 0xFF000000L: %8X, %8X\n", 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyph, glyph, extraBitGlyphs[glyph], glyphs[glyph]); 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(biasedIndices, 1024, status); 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("getCharIndices(biasedIndices, 1024, status) failed.\n"); 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (glyph = 0; glyph < glyphCount; glyph += 1) { 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (biasedIndices[glyph] != (indices[glyph] + 1024)) { 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("biasedIndices[%d] != indices[%d] + 1024: %8X, %8X\n", 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyph, glyph, biasedIndices[glyph], indices[glyph]); 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = LE_NO_ERROR; 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (glyph = 0; glyph <= glyphCount; glyph += 1) { 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float x = 0.0, y = 0.0; 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPosition(glyph, x, y, status); 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("getGlyphPosition(%d, x, y, status) failed.\n", glyph); 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (x != positions[glyph*2] || y != positions[glyph*2 + 1]) { 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("getGlyphPosition(%d, x, y, status) returned bad position: (%f, %f) != (%f, %f)\n", 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyph, x, y, positions[glyph*2], positions[glyph*2 + 1]); 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubail: 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete engine; 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete font; 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_bool compareResults(const char *testID, TestResult *expected, TestResult *actual) 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* NOTE: we'll stop on the first failure 'cause once there's one error, it may cascade... */ 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (actual->glyphCount != expected->glyphCount) { 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Test %s: incorrect glyph count: exptected %d, got %d\n", 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testID, expected->glyphCount, actual->glyphCount); 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 i; 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < actual->glyphCount; i += 1) { 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (actual->glyphs[i] != expected->glyphs[i]) { 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Test %s: incorrect id for glyph %d: expected %4X, got %4X\n", 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testID, i, expected->glyphs[i], actual->glyphs[i]); 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < actual->glyphCount; i += 1) { 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (actual->indices[i] != expected->indices[i]) { 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Test %s: incorrect index for glyph %d: expected %8X, got %8X\n", 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testID, i, expected->indices[i], actual->indices[i]); 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i <= actual->glyphCount; i += 1) { 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double xError = uprv_fabs(actual->positions[i * 2] - expected->positions[i * 2]); 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (xError > 0.0001) { 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Test %s: incorrect x position for glyph %d: expected %f, got %f\n", 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testID, i, expected->positions[i * 2], actual->positions[i * 2]); 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double yError = uprv_fabs(actual->positions[i * 2 + 1] - expected->positions[i * 2 + 1]); 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (yError < 0) { 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru yError = -yError; 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (yError > 0.0001) { 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Test %s: incorrect y position for glyph %d: expected %f, got %f\n", 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testID, i, expected->positions[i * 2 + 1], actual->positions[i * 2 + 1]); 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void checkFontVersion(PortableFontInstance *fontInstance, const char *testVersionString, 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_uint32 testChecksum, const char *testID) 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_uint32 fontChecksum = fontInstance->getFontChecksum(); 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fontChecksum != testChecksum) { 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *fontVersionString = fontInstance->getNameString(NAME_VERSION_STRING, 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH); 38885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const LEUnicode *uFontVersionString = NULL; 38985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 39085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // The standard recommends that the Macintosh Roman/English name string be present, but 39185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // if it's not, try the Microsoft Unicode/English string. 39285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (fontVersionString == NULL) { 39385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uFontVersionString = fontInstance->getUnicodeNameString(NAME_VERSION_STRING, 39485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho PLATFORM_MICROSOFT, MICROSOFT_UNICODE_BMP, MICROSOFT_ENGLISH); 39585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_info("Test %s: this may not be the same font used to generate the test data.\n", testID); 39885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 39985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (uFontVersionString != NULL) { 40085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho log_info("Your font's version string is \"%S\"\n", uFontVersionString); 40185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fontInstance->deleteNameString(uFontVersionString); 40285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 40385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho log_info("Your font's version string is \"%s\"\n", fontVersionString); 40485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fontInstance->deleteNameString(fontVersionString); 40585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 40685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_info("The expected version string is \"%s\"\n", testVersionString); 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_info("If you see errors, they may be due to the version of the font you're using.\n"); 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Returns the path to icu/source/test/testdata/ */ 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char *getSourceTestData() { 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *srcDataDir = NULL; 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_TOPSRCDIR 41659d709d503bab6e2b61931737e662dd293b40578ccornelius srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING; 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING; 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FILE *f = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"rbbitst.txt", "r"); 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (f != NULL) { 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We're in icu/source/test/letest/ */ 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fclose(f); 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We're in icu/source/test/letest/(Debug|Release) */ 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING; 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return srcDataDir; 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char *getPath(char buffer[2048], const char *filename) { 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *testDataDirectory = getSourceTestData(); 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcpy(buffer, testDataDirectory); 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcat(buffer, filename); 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return buffer; 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_uint32 *getHexArray(const UnicodeString &numbers, int32_t &arraySize) 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset = -1; 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru arraySize = 1; 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) { 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru arraySize += 1; 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_uint32 *array = NEW_ARRAY(le_uint32, arraySize); 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char number[16]; 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 count = 0; 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 start = 0, end = 0; 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 len = 0; 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // trim leading whitespace 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(u_isUWhiteSpace(numbers[start])) { 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start += 1; 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((end = numbers.indexOf(CH_COMMA, start)) >= 0) { 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV); 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru number[len] = '\0'; 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = end + 1; 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sscanf(number, "%x", &array[count++]); 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // trim whitespace following the comma 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(u_isUWhiteSpace(numbers[start])) { 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start += 1; 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // trim trailing whitespace 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru end = numbers.length(); 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(u_isUWhiteSpace(numbers[end - 1])) { 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru end -= 1; 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV); 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru number[len] = '\0'; 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sscanf(number, "%x", &array[count]); 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return array; 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querufloat *getFloatArray(const UnicodeString &numbers, int32_t &arraySize) 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset = -1; 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru arraySize = 1; 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) { 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru arraySize += 1; 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float *array = NEW_ARRAY(float, arraySize); 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char number[32]; 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 count = 0; 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 start = 0, end = 0; 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 len = 0; 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // trim leading whitespace 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(u_isUWhiteSpace(numbers[start])) { 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start += 1; 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((end = numbers.indexOf(CH_COMMA, start)) >= 0) { 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV); 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru number[len] = '\0'; 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = end + 1; 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sscanf(number, "%f", &array[count++]); 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // trim whiteapce following the comma 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(u_isUWhiteSpace(numbers[start])) { 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start += 1; 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(u_isUWhiteSpace(numbers[start])) { 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start += 1; 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // trim trailing whitespace 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru end = numbers.length(); 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(u_isUWhiteSpace(numbers[end - 1])) { 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru end -= 1; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV); 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru number[len] = '\0'; 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sscanf(number, "%f", &array[count]); 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return array; 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLEFontInstance *openFont(const char *fontName, const char *checksum, const char *version, const char *testID) 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char path[2048]; 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PortableFontInstance *font; 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode fontStatus = LE_NO_ERROR; 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru font = new PortableFontInstance(getPath(path, fontName), 12, fontStatus); 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(fontStatus)) { 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_info("Test %s: can't open font %s - test skipped.\n", testID, fontName); 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete font; 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_uint32 cksum = 0; 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sscanf(checksum, "%x", &cksum); 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru checkFontVersion(font, version, cksum, testID); 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return font; 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV DataDrivenTest(void) 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_REGULAR_EXPRESSIONS 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char path[2048]; 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *testFilePath = getPath(path, "letest.xml"); 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UXMLParser *parser = UXMLParser::createParser(status); 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UXMLElement *root = parser->parseFile(testFilePath, status); 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (root == NULL) { 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Could not open the test data file: %s\n", testFilePath); 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete parser; 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString test_case = UNICODE_STRING_SIMPLE("test-case"); 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString test_text = UNICODE_STRING_SIMPLE("test-text"); 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString test_font = UNICODE_STRING_SIMPLE("test-font"); 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString result_glyphs = UNICODE_STRING_SIMPLE("result-glyphs"); 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString result_indices = UNICODE_STRING_SIMPLE("result-indices"); 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString result_positions = UNICODE_STRING_SIMPLE("result-positions"); 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // test-case attributes 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString id_attr = UNICODE_STRING_SIMPLE("id"); 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString script_attr = UNICODE_STRING_SIMPLE("script"); 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString lang_attr = UNICODE_STRING_SIMPLE("lang"); 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // test-font attributes 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString name_attr = UNICODE_STRING_SIMPLE("name"); 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString ver_attr = UNICODE_STRING_SIMPLE("version"); 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString cksum_attr = UNICODE_STRING_SIMPLE("checksum"); 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UXMLElement *testCase; 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t tc = 0; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((testCase = root->nextChildElement(tc)) != NULL) { 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (testCase->getTagName().compare(test_case) == 0) { 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *id = getCString(testCase->getAttribute(id_attr)); 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *script = getCString(testCase->getAttribute(script_attr)); 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *lang = getCString(testCase->getAttribute(lang_attr)); 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEFontInstance *font = NULL; 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UXMLElement *element; 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t ec = 0; 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t charCount = 0; 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t typoFlags = 3; // kerning + ligatures... 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptCode scriptCode; 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 languageCode = -1; 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString text, glyphs, indices, positions; 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t glyphCount = 0, indexCount = 0, positionCount = 0; 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestResult expected = {0, NULL, NULL, NULL}; 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestResult actual = {0, NULL, NULL, NULL}; 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode success = LE_NO_ERROR; 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LayoutEngine *engine = NULL; 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uscript_getCode(script, &scriptCode, 1, &status); 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("invalid script name: %s.\n", script); 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto free_c_strings; 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lang != NULL) { 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru languageCode = getLanguageCode(lang); 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (languageCode < 0) { 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("invalid language name: %s.\n", lang); 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto free_c_strings; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((element = testCase->nextChildElement(ec)) != NULL) { 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString tag = element->getTagName(); 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // TODO: make sure that each element is only used once. 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tag.compare(test_font) == 0) { 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *fontName = getCString(element->getAttribute(name_attr)); 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *fontVer = getCString(element->getAttribute(ver_attr)); 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *fontCksum = getCString(element->getAttribute(cksum_attr)); 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru font = openFont(fontName, fontCksum, fontVer, id); 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freeCString(fontCksum); 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freeCString(fontVer); 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freeCString(fontName); 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (font == NULL) { 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // warning message already displayed... 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto free_c_strings; 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (tag.compare(test_text) == 0) { 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru text = element->getText(TRUE); 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charCount = text.length(); 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (tag.compare(result_glyphs) == 0) { 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphs = element->getText(TRUE); 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (tag.compare(result_indices) == 0) { 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indices = element->getText(TRUE); 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (tag.compare(result_positions) == 0) { 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru positions = element->getText(TRUE); 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // an unknown tag... 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *cTag = getCString(&tag); 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_info("Test %s: unknown element with tag \"%s\"\n", id, cTag); 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freeCString(cTag); 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // TODO: make sure that the font, test-text, result-glyphs, result-indices and result-positions 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // have all been provided 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (font == NULL) { 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode fontStatus = LE_NO_ERROR; 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru font = new SimpleFontInstance(12, fontStatus); 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru typoFlags |= 0x80000000L; // use CharSubstitutionFilter... 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru expected.glyphs = (LEGlyphID *) getHexArray(glyphs, glyphCount); 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru expected.indices = (le_int32 *) getHexArray(indices, indexCount); 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru expected.positions = getFloatArray(positions, positionCount); 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru expected.glyphCount = glyphCount; 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (glyphCount < charCount || indexCount != glyphCount || positionCount < glyphCount * 2 + 2) { 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Test %s: inconsistent input data: charCount = %d, glyphCount = %d, indexCount = %d, positionCount = %d\n", 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru id, charCount, glyphCount, indexCount, positionCount); 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto free_expected; 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine = LayoutEngine::layoutEngineFactory(font, scriptCode, languageCode, typoFlags, success); 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(success)) { 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Test %s: could not create a LayoutEngine.\n", id); 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto free_expected; 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru actual.glyphCount = engine->layoutChars(text.getBuffer(), 0, charCount, charCount, getRTL(text), 0, 0, success); 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru actual.glyphs = NEW_ARRAY(LEGlyphID, actual.glyphCount); 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru actual.indices = NEW_ARRAY(le_int32, actual.glyphCount); 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru actual.positions = NEW_ARRAY(float, actual.glyphCount * 2 + 2); 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(actual.glyphs, success); 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(actual.indices, success); 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPositions(actual.positions, success); 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru compareResults(id, &expected, &actual); 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(actual.positions); 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(actual.indices); 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(actual.glyphs); 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete engine; 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 71559d709d503bab6e2b61931737e662dd293b40578ccornelius log_verbose("OK - %4d glyphs: %s\n", actual.glyphCount, id); 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querufree_expected: 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(expected.positions); 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(expected.indices); 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELETE_ARRAY(expected.glyphs); 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete font; 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querufree_c_strings: 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freeCString(lang); 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freeCString(script); 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freeCString(id); 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete root; 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete parser; 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * From ticket:5923: 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Build a paragraph that contains a mixture of left to right and right to left text. 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Break it into multiple lines and make sure that the glyphToCharMap for run in each 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * line is correct. 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Note: it might be a good idea to also check the glyphs and positions for each run, 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that we get the expected number of runs per line and that the line breaks are where 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we expect them to be. Really, it would be a good idea to make a whole test suite 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * for ParagraphLayout. 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV GlyphToCharTest(void) 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 751fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode status = LE_NO_ERROR; 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEFontInstance *font; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FontRuns fontRuns(0); 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ParagraphLayout *paragraphLayout; 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const ParagraphLayout::Line *line; 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is the same text that's in <icu>/source/samples/layout/Sample.txt 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEUnicode chars[] = { 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*BOM*/ 0x0054, 0x0068, 0x0065, 0x0020, 0x004c, 0x0061, 0x0079, 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x006f, 0x0075, 0x0074, 0x0045, 0x006e, 0x0067, 0x0069, 0x006e, 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0065, 0x0020, 0x0064, 0x006f, 0x0065, 0x0073, 0x0020, 0x0061, 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x006c, 0x006c, 0x0020, 0x0074, 0x0068, 0x0065, 0x0020, 0x0077, 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x006f, 0x0072, 0x006b, 0x0020, 0x006e, 0x0065, 0x0063, 0x0065, 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0073, 0x0073, 0x0061, 0x0072, 0x0079, 0x0020, 0x0074, 0x006f, 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0064, 0x0069, 0x0073, 0x0070, 0x006c, 0x0061, 0x0079, 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0055, 0x006e, 0x0069, 0x0063, 0x006f, 0x0064, 0x0065, 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x0020, 0x0077, 0x0072, 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0069, 0x0074, 0x0074, 0x0065, 0x006e, 0x0020, 0x0069, 0x006e, 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x006c, 0x0061, 0x006e, 0x0067, 0x0075, 0x0061, 0x0067, 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0065, 0x0073, 0x0020, 0x0077, 0x0069, 0x0074, 0x0068, 0x0020, 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0063, 0x006f, 0x006d, 0x0070, 0x006c, 0x0065, 0x0078, 0x0020, 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0077, 0x0072, 0x0069, 0x0074, 0x0069, 0x006e, 0x0067, 0x0020, 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0073, 0x0079, 0x0073, 0x0074, 0x0065, 0x006d, 0x0073, 0x0020, 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0073, 0x0075, 0x0063, 0x0068, 0x0020, 0x0061, 0x0073, 0x0020, 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0048, 0x0069, 0x006e, 0x0064, 0x0069, 0x0020, 0x0028, 0x0939, 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x093f, 0x0928, 0x094d, 0x0926, 0x0940, 0x0029, 0x0020, 0x0054, 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0068, 0x0061, 0x0069, 0x0020, 0x0028, 0x0e44, 0x0e17, 0x0e22, 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0029, 0x0020, 0x0061, 0x006e, 0x0064, 0x0020, 0x0041, 0x0072, 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0061, 0x0062, 0x0069, 0x0063, 0x0020, 0x0028, 0x0627, 0x0644, 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0639, 0x0631, 0x0628, 0x064a, 0x0629, 0x0029, 0x002e, 0x0020, 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0048, 0x0065, 0x0072, 0x0065, 0x0027, 0x0073, 0x0020, 0x0061, 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0073, 0x0061, 0x006d, 0x0070, 0x006c, 0x0065, 0x0020, 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x006f, 0x0066, 0x0020, 0x0073, 0x006f, 0x006d, 0x0065, 0x0020, 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0074, 0x0065, 0x0078, 0x0074, 0x0020, 0x0077, 0x0072, 0x0069, 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0074, 0x0074, 0x0065, 0x006e, 0x0020, 0x0069, 0x006e, 0x0020, 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0053, 0x0061, 0x006e, 0x0073, 0x006b, 0x0072, 0x0069, 0x0074, 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x003a, 0x0020, 0x0936, 0x094d, 0x0930, 0x0940, 0x092e, 0x0926, 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x094d, 0x0020, 0x092d, 0x0917, 0x0935, 0x0926, 0x094d, 0x0917, 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0940, 0x0924, 0x093e, 0x0020, 0x0905, 0x0927, 0x094d, 0x092f, 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x093e, 0x092f, 0x0020, 0x0905, 0x0930, 0x094d, 0x091c, 0x0941, 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0928, 0x0020, 0x0935, 0x093f, 0x0937, 0x093e, 0x0926, 0x0020, 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x092f, 0x094b, 0x0917, 0x0020, 0x0927, 0x0943, 0x0924, 0x0930, 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x093e, 0x0937, 0x094d, 0x091f, 0x094d, 0x0930, 0x0020, 0x0909, 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0935, 0x093e, 0x091a, 0x0964, 0x0020, 0x0927, 0x0930, 0x094d, 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x092e, 0x0915, 0x094d, 0x0937, 0x0947, 0x0924, 0x094d, 0x0930, 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0947, 0x0020, 0x0915, 0x0941, 0x0930, 0x0941, 0x0915, 0x094d, 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0937, 0x0947, 0x0924, 0x094d, 0x0930, 0x0947, 0x0020, 0x0938, 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x092e, 0x0935, 0x0947, 0x0924, 0x093e, 0x0020, 0x092f, 0x0941, 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x092f, 0x0941, 0x0924, 0x094d, 0x0938, 0x0935, 0x0903, 0x0020, 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x092e, 0x093e, 0x092e, 0x0915, 0x093e, 0x0903, 0x0020, 0x092a, 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x093e, 0x0923, 0x094d, 0x0921, 0x0935, 0x093e, 0x0936, 0x094d, 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x091a, 0x0948, 0x0935, 0x0020, 0x0915, 0x093f, 0x092e, 0x0915, 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0941, 0x0930, 0x094d, 0x0935, 0x0924, 0x0020, 0x0938, 0x0902, 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x091c, 0x092f, 0x0020, 0x0048, 0x0065, 0x0072, 0x0065, 0x0027, 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0073, 0x0020, 0x0061, 0x0020, 0x0073, 0x0061, 0x006d, 0x0070, 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x006c, 0x0065, 0x0020, 0x006f, 0x0066, 0x0020, 0x0073, 0x006f, 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x006d, 0x0065, 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x0020, 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0077, 0x0072, 0x0069, 0x0074, 0x0074, 0x0065, 0x006e, 0x0020, 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0069, 0x006e, 0x0020, 0x0041, 0x0072, 0x0061, 0x0062, 0x0069, 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0063, 0x003a, 0x0020, 0x0623, 0x0633, 0x0627, 0x0633, 0x064b, 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0627, 0x060c, 0x0020, 0x062a, 0x062a, 0x0639, 0x0627, 0x0645, 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0644, 0x0020, 0x0627, 0x0644, 0x062d, 0x0648, 0x0627, 0x0633, 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x064a, 0x0628, 0x0020, 0x0641, 0x0642, 0x0637, 0x0020, 0x0645, 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0639, 0x0020, 0x0627, 0x0644, 0x0623, 0x0631, 0x0642, 0x0627, 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0645, 0x060c, 0x0020, 0x0648, 0x062a, 0x0642, 0x0648, 0x0645, 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0628, 0x062a, 0x062e, 0x0632, 0x064a, 0x0646, 0x0020, 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0627, 0x0644, 0x0623, 0x062d, 0x0631, 0x0641, 0x0020, 0x0648, 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0627, 0x0644, 0x0645, 0x062d, 0x0627, 0x0631, 0x0641, 0x0020, 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0627, 0x0644, 0x0623, 0x062e, 0x0631, 0x0649, 0x0020, 0x0628, 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0639, 0x062f, 0x0020, 0x0623, 0x0646, 0x0020, 0x062a, 0x064f, 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0639, 0x0637, 0x064a, 0x0020, 0x0631, 0x0642, 0x0645, 0x0627, 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0645, 0x0639, 0x064a, 0x0646, 0x0627, 0x0020, 0x0644, 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0643, 0x0644, 0x0020, 0x0648, 0x0627, 0x062d, 0x062f, 0x0020, 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0645, 0x0646, 0x0647, 0x0627, 0x002e, 0x0020, 0x0648, 0x0642, 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0628, 0x0644, 0x0020, 0x0627, 0x062e, 0x062a, 0x0631, 0x0627, 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0639, 0x0020, 0x0022, 0x064a, 0x0648, 0x0646, 0x0650, 0x0643, 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0648, 0x062f, 0x0022, 0x060c, 0x0020, 0x0643, 0x0627, 0x0646, 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0647, 0x0646, 0x0627, 0x0643, 0x0020, 0x0645, 0x0626, 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0627, 0x062a, 0x0020, 0x0627, 0x0644, 0x0623, 0x0646, 0x0638, 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0645, 0x0629, 0x0020, 0x0644, 0x0644, 0x062a, 0x0634, 0x0641, 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x064a, 0x0631, 0x0020, 0x0648, 0x062a, 0x062e, 0x0635, 0x064a, 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0635, 0x0020, 0x0647, 0x0630, 0x0647, 0x0020, 0x0627, 0x0644, 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0623, 0x0631, 0x0642, 0x0627, 0x0645, 0x0020, 0x0644, 0x0644, 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0645, 0x062d, 0x0627, 0x0631, 0x0641, 0x060c, 0x0020, 0x0648, 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0644, 0x0645, 0x0020, 0x064a, 0x0648, 0x062c, 0x062f, 0x0020, 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0646, 0x0638, 0x0627, 0x0645, 0x0020, 0x062a, 0x0634, 0x0641, 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x064a, 0x0631, 0x0020, 0x0648, 0x0627, 0x062d, 0x062f, 0x0020, 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x064a, 0x062d, 0x062a, 0x0648, 0x064a, 0x0020, 0x0639, 0x0644, 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0649, 0x0020, 0x062c, 0x0645, 0x064a, 0x0639, 0x0020, 0x0627, 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0644, 0x0645, 0x062d, 0x0627, 0x0631, 0x0641, 0x0020, 0x0627, 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0644, 0x0636, 0x0631, 0x0648, 0x0631, 0x064a, 0x0629, 0x0020, 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0061, 0x006e, 0x0064, 0x0020, 0x0068, 0x0065, 0x0072, 0x0065, 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0027, 0x0073, 0x0020, 0x0061, 0x0020, 0x0073, 0x0061, 0x006d, 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0070, 0x006c, 0x0065, 0x0020, 0x006f, 0x0066, 0x0020, 0x0073, 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x006f, 0x006d, 0x0065, 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0077, 0x0072, 0x0069, 0x0074, 0x0074, 0x0065, 0x006e, 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0020, 0x0069, 0x006e, 0x0020, 0x0054, 0x0068, 0x0061, 0x0069, 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x003a, 0x0020, 0x0e1a, 0x0e17, 0x0e17, 0x0e35, 0x0e48, 0x0e51, 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e1e, 0x0e32, 0x0e22, 0x0e38, 0x0e44, 0x0e0b, 0x0e42, 0x0e04, 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e25, 0x0e19, 0x0e42, 0x0e14, 0x0e42, 0x0e23, 0x0e18, 0x0e35, 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e2d, 0x0e32, 0x0e28, 0x0e31, 0x0e22, 0x0e2d, 0x0e22, 0x0e39, 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e48, 0x0e17, 0x0e48, 0x0e32, 0x0e21, 0x0e01, 0x0e25, 0x0e32, 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e07, 0x0e17, 0x0e38, 0x0e48, 0x0e07, 0x0e43, 0x0e2b, 0x0e0d, 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e48, 0x0e43, 0x0e19, 0x0e41, 0x0e04, 0x0e19, 0x0e0b, 0x0e31, 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e2a, 0x0e01, 0x0e31, 0x0e1a, 0x0e25, 0x0e38, 0x0e07, 0x0e40, 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e2e, 0x0e19, 0x0e23, 0x0e35, 0x0e0a, 0x0e32, 0x0e27, 0x0e44, 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e23, 0x0e48, 0x0e41, 0x0e25, 0x0e30, 0x0e1b, 0x0e49, 0x0e32, 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e40, 0x0e2d, 0x0e47, 0x0e21, 0x0e20, 0x0e23, 0x0e23, 0x0e22, 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e32, 0x0e0a, 0x0e32, 0x0e27, 0x0e44, 0x0e23, 0x0e48, 0x0e1a, 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e49, 0x0e32, 0x0e19, 0x0e02, 0x0e2d, 0x0e07, 0x0e1e, 0x0e27, 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e01, 0x0e40, 0x0e02, 0x0e32, 0x0e2b, 0x0e25, 0x0e31, 0x0e07, 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e40, 0x0e25, 0x0e47, 0x0e01, 0x0e40, 0x0e1e, 0x0e23, 0x0e32, 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e30, 0x0e44, 0x0e21, 0x0e49, 0x0e2a, 0x0e23, 0x0e49, 0x0e32, 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e07, 0x0e1a, 0x0e49, 0x0e32, 0x0e19, 0x0e15, 0x0e49, 0x0e2d, 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e07, 0x0e02, 0x0e19, 0x0e21, 0x0e32, 0x0e14, 0x0e49, 0x0e27, 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e22, 0x0e40, 0x0e01, 0x0e27, 0x0e35, 0x0e22, 0x0e19, 0x0e40, 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e1b, 0x0e47, 0x0e19, 0x0e23, 0x0e30, 0x0e22, 0x0e30, 0x0e17, 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e32, 0x0e07, 0x0e2b, 0x0e25, 0x0e32, 0x0e22, 0x0e44, 0x0e21, 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x0e25, 0x0e4c 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 charCount = LE_ARRAY_SIZE(chars); 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 charIndex = 0, lineNumber = 1; 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const float lineWidth = 600; 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru font = new SimpleFontInstance(12, status); 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto finish; 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fontRuns.add(font, charCount); 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru paragraphLayout = new ParagraphLayout(chars, charCount, &fontRuns, NULL, NULL, NULL, 0, FALSE, status); 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto close_font; 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru paragraphLayout->reflow(); 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while ((line = paragraphLayout->nextLine(lineWidth)) != NULL) { 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 runCount = line->countRuns(); 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(le_int32 run = 0; run < runCount; run += 1) { 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const ParagraphLayout::VisualRun *visualRun = line->getVisualRun(run); 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount = visualRun->getGlyphCount(); 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const le_int32 *glyphToCharMap = visualRun->getGlyphToCharMap(); 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (visualRun->getDirection() == UBIDI_RTL) { 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * For a right to left run, make sure that the character indices 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * increase from the right most glyph to the left most glyph. If 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * there are any one to many glyph substitutions, we might get several 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * glyphs in a row with the same character index. 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(le_int32 i = glyphCount - 1; i >= 0; i -= 1) { 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ix = glyphToCharMap[i]; 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ix != charIndex) { 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ix != charIndex - 1) { 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Bad glyph to char index for glyph %d on line %d: expected %d, got %d\n", 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i, lineNumber, charIndex, ix); 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto close_paragraph; // once there's one error, we can't count on anything else... 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charIndex += 1; 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We can't just check the order of the character indices 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * for left to right runs because Indic text might have been 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * reordered. What we can do is find the minimum and maximum 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * character indices in the run and make sure that the minimum 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is equal to charIndex and then advance charIndex to the maximum. 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 minIndex = 0x7FFFFFFF, maxIndex = -1; 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(le_int32 i = 0; i < glyphCount; i += 1) { 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ix = glyphToCharMap[i]; 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ix > maxIndex) { 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxIndex = ix; 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ix < minIndex) { 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minIndex = ix; 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (minIndex != charIndex) { 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log_err("Bad minIndex for run %d on line %d: expected %d, got %d\n", 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru run, lineNumber, charIndex, minIndex); 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto close_paragraph; // once there's one error, we can't count on anything else... 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charIndex = maxIndex + 1; 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lineNumber += 1; 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclose_paragraph: 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete paragraphLayout; 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclose_font: 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete font; 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querufinish: 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 962fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void addAllTests(TestNode **root) 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addTest(root, &ScriptTest, "api/ScriptTest"); 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addTest(root, &ParamTest, "api/ParameterTest"); 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addTest(root, &FactoryTest, "api/FactoryTest"); 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addTest(root, &AccessTest, "layout/AccessTest"); 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addTest(root, &DataDrivenTest, "layout/DataDrivenTest"); 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addTest(root, &GlyphToCharTest, "paragraph/GlyphToCharTest"); 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addCTests(root); 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* returns the path to icu/source/data/out */ 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char *ctest_dataOutDir() 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static const char *dataOutDir = NULL; 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(dataOutDir) { 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dataOutDir; 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to point to the top of the build hierarchy, which may or 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // may not be the same as the source directory, depending on 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the configure options used. At any rate, 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set the data path to the built data from this directory. 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The value is complete with quotes, so it can be used 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // as-is as a string constant. 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_TOPBUILDDIR) 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 9978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius dataOutDir = U_TOPBUILDDIR "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING; 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* On Windows, the file name obtained from __FILE__ includes a full path. 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This file is "wherever\icu\source\test\cintltst\cintltst.c" 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Change to "wherever\icu\source\data" 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static char p[sizeof(__FILE__) + 20]; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *pBackSlash; 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int i; 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcpy(p, __FILE__); 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We want to back over three '\' chars. */ 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Only Windows should end up here, so looking for '\' is safe. */ 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i=1; i<=3; i++) { 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBackSlash = strrchr(p, U_FILE_SEP_CHAR); 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pBackSlash != NULL) { 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pBackSlash = 0; /* Truncate the string at the '\' */ 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pBackSlash != NULL) { 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We found and truncated three names from the path. 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Now append "source\data" and set the environment 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING); 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dataOutDir = p; 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* __FILE__ on MSVC7 does not contain the directory */ 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FILE *file = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r"); 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (file) { 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fclose(file); 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dataOutDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING; 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dataOutDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING; 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dataOutDir; 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ctest_setICU_DATA - if the ICU_DATA environment variable is not already 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * set, try to deduce the directory in which ICU was built, 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and set ICU_DATA to "icu/source/data" in that location. 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The intent is to allow the tests to have a good chance 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * of running without requiring that the user manually set 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * ICU_DATA. Common data isn't a problem, since it is 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * picked up via a static (build time) reference, but the 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * tests dynamically load some data. 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void ctest_setICU_DATA() { 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* No location for the data dir was identifiable. 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Add other fallbacks for the test data location here if the need arises 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (getenv("ICU_DATA") == NULL) { 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If ICU_DATA isn't set, set it to the usual location */ 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_setDataDirectory(ctest_dataOutDir()); 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint main(int argc, char* argv[]) 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nerrors = 0; 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestNode *root = NULL; 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UDate startTime, endTime; 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t diffTime; 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startTime = uprv_getUTCtime(); 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 107485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (!initArgs(argc, argv, NULL, NULL)) { 107585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Error already displayed. */ 107685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return -1; 107785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 107885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Check whether ICU will initialize without forcing the build data directory into 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the ICU_DATA path. Success here means either the data dll contains data, or that 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * this test program was run with ICU_DATA set externally. Failure of this check 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is normal when ICU data is not packaged into a shared library. 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Whether or not this test succeeds, we want to cleanup and reinitialize 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * with a data path so that data loading from individual files can be tested. 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_init(&errorCode); 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(errorCode)) { 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "#### Note: ICU Init without build-specific setDataDirectory() failed.\n"); 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_cleanup(); 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errorCode = U_ZERO_ERROR; 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 109785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (!initArgs(argc, argv, NULL, NULL)) { 109885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Error already displayed. */ 109985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return -1; 110085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 110185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* Initialize ICU */ 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ctest_setICU_DATA(); /* u_setDataDirectory() must happen Before u_init() */ 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_init(&errorCode); 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(errorCode)) { 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "#### ERROR! %s: u_init() failed with status = \"%s\".\n" 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "*** Check the ICU_DATA environment variable and \n" 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "*** check that the data files are present.\n", argv[0], u_errorName(errorCode)); 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addAllTests(&root); 111485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho nerrors = runTestRequest(root, argc, argv); 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cleanUpTestTree(root); 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_cleanup(); 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru endTime = uprv_getUTCtime(); 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru diffTime = (int32_t)(endTime - startTime); 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf("Elapsed Time: %02d:%02d:%02d.%03d\n", 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int)((diffTime%U_MILLIS_PER_DAY)/U_MILLIS_PER_HOUR), 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int)((diffTime%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE), 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int)((diffTime%U_MILLIS_PER_MINUTE)/U_MILLIS_PER_SECOND), 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int)(diffTime%U_MILLIS_PER_SECOND)); 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return nerrors; 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1130