1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************************* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 459d709d503bab6e2b61931737e662dd293b40578ccornelius * Copyright (C) 1999-2013, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************************* 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * file name: gendata.cpp 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * created on: 11/03/2000 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * created by: Eric R. Mader 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h> 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <time.h> 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/unistr.h" 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uscript.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ubidi.h" 2259d709d503bab6e2b61931737e662dd293b40578ccornelius#include "unicode/ustring.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LETypes.h" 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LEScripts.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LayoutEngine.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "PortableFontInstance.h" 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "SimpleFontInstance.h" 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "xmlparser.h" 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "letsutil.h" 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "letest.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_USE 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 3859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic LEErrorCode overallStatus = LE_NO_ERROR; 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct TestInput 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *fontName; 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *text; 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 textLength; 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 scriptCode; 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_bool rightToLeft; 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 4859d709d503bab6e2b61931737e662dd293b40578ccornelius/* Returns the path to icu/source/test/testdata/ */ 4959d709d503bab6e2b61931737e662dd293b40578ccorneliusconst char *getSourceTestData() { 5059d709d503bab6e2b61931737e662dd293b40578ccornelius const char *srcDataDir = NULL; 5159d709d503bab6e2b61931737e662dd293b40578ccornelius#ifdef U_TOPSRCDIR 5259d709d503bab6e2b61931737e662dd293b40578ccornelius srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING; 5359d709d503bab6e2b61931737e662dd293b40578ccornelius#else 5459d709d503bab6e2b61931737e662dd293b40578ccornelius srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING; 5559d709d503bab6e2b61931737e662dd293b40578ccornelius FILE *f = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"rbbitst.txt", "r"); 5659d709d503bab6e2b61931737e662dd293b40578ccornelius 5759d709d503bab6e2b61931737e662dd293b40578ccornelius if (f != NULL) { 5859d709d503bab6e2b61931737e662dd293b40578ccornelius /* We're in icu/source/test/letest/ */ 5959d709d503bab6e2b61931737e662dd293b40578ccornelius fclose(f); 6059d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 6159d709d503bab6e2b61931737e662dd293b40578ccornelius /* We're in icu/source/test/letest/(Debug|Release) */ 6259d709d503bab6e2b61931737e662dd293b40578ccornelius srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING; 6359d709d503bab6e2b61931737e662dd293b40578ccornelius } 6459d709d503bab6e2b61931737e662dd293b40578ccornelius#endif 6559d709d503bab6e2b61931737e662dd293b40578ccornelius 6659d709d503bab6e2b61931737e662dd293b40578ccornelius return srcDataDir; 6759d709d503bab6e2b61931737e662dd293b40578ccornelius} 6859d709d503bab6e2b61931737e662dd293b40578ccornelius 6959d709d503bab6e2b61931737e662dd293b40578ccorneliusconst char *getPath(char buffer[2048], const char *filename) { 7059d709d503bab6e2b61931737e662dd293b40578ccornelius const char *testDataDirectory = getSourceTestData(); 7159d709d503bab6e2b61931737e662dd293b40578ccornelius 7259d709d503bab6e2b61931737e662dd293b40578ccornelius strcpy(buffer, testDataDirectory); 7359d709d503bab6e2b61931737e662dd293b40578ccornelius strcat(buffer, filename); 7459d709d503bab6e2b61931737e662dd293b40578ccornelius 7559d709d503bab6e2b61931737e662dd293b40578ccornelius return buffer; 7659d709d503bab6e2b61931737e662dd293b40578ccornelius} 7759d709d503bab6e2b61931737e662dd293b40578ccornelius 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * FIXME: should use the output file name and the current date. 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst char *header = 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "\n" 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "<!--\n" 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " Copyright (c) 1999-%4.4d International Business Machines\n" 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " Corporation and others. All rights reserved.\n" 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "\n" 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT\n" 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " UNLESS YOU REALLY KNOW WHAT YOU'RE DOING.\n" 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "\n" 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " file name: letest.xml\n" 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " generated on: %s\n" 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " generated by: gendata.cpp\n" 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "-->\n" 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "\n" 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "<layout-tests>\n"; 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid dumpLongs(FILE *file, const char *tag, le_int32 *longs, le_int32 count) { 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char lineBuffer[8 * 12 + 2]; 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 bufp = 0; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(file, " <%s>\n", tag); 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < count; i += 1) { 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (i % 8 == 0 && bufp != 0) { 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(file, " %s\n", lineBuffer); 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bufp = 0; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bufp += sprintf(&lineBuffer[bufp], "0x%8.8X, ", longs[i]); 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (bufp != 0) { 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lineBuffer[bufp - 2] = '\0'; 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(file, " %s\n", lineBuffer); 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(file, " </%s>\n\n", tag); 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid dumpFloats(FILE *file, const char *tag, float *floats, le_int32 count) { 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char lineBuffer[8 * 16 + 2]; 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 bufp = 0; 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(file, " <%s>\n", tag); 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < count; i += 1) { 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (i % 8 == 0 && bufp != 0) { 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(file, " %s\n", lineBuffer); 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bufp = 0; 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bufp += sprintf(&lineBuffer[bufp], "%f, ", floats[i]); 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (bufp != 0) { 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lineBuffer[bufp - 2] = '\0'; 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(file, " %s\n", lineBuffer); 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(file, " </%s>\n", tag); 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14459d709d503bab6e2b61931737e662dd293b40578ccorneliusint main(int argc, char *argv[]) 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 14759d709d503bab6e2b61931737e662dd293b40578ccornelius const char *gendataFile = "gendata.xml"; 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FILE *outputFile = fopen(argv[1], "w"); 14959d709d503bab6e2b61931737e662dd293b40578ccornelius if(argc>2) { 15059d709d503bab6e2b61931737e662dd293b40578ccornelius gendataFile = argv[2]; 15159d709d503bab6e2b61931737e662dd293b40578ccornelius } 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru time_t now = time(NULL); 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru struct tm *local = localtime(&now); 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *tmFormat = "%m/%d/%Y %I:%M:%S %p %Z"; 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char tmString[64]; 15659d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint32 count = 0; 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru strftime(tmString, 64, tmFormat, local); 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(outputFile, header, local->tm_year + 1900, tmString); 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UXMLParser *parser = UXMLParser::createParser(status); 16159d709d503bab6e2b61931737e662dd293b40578ccornelius UXMLElement *root = parser->parseFile(gendataFile, status); 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (root == NULL) { 16459d709d503bab6e2b61931737e662dd293b40578ccornelius printf("Error: Could not open %s\n", gendataFile); 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete parser; 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 16759d709d503bab6e2b61931737e662dd293b40578ccornelius } else if(U_FAILURE(status)) { 16859d709d503bab6e2b61931737e662dd293b40578ccornelius printf("Error reading %s: %s\n", gendataFile, u_errorName(status)); 16959d709d503bab6e2b61931737e662dd293b40578ccornelius return -2; 17059d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 17159d709d503bab6e2b61931737e662dd293b40578ccornelius printf("Reading %s\n", gendataFile); 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString test_case = UNICODE_STRING_SIMPLE("test-case"); 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString test_text = UNICODE_STRING_SIMPLE("test-text"); 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString test_font = UNICODE_STRING_SIMPLE("test-font"); 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // test-case attributes 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString id_attr = UNICODE_STRING_SIMPLE("id"); 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString script_attr = UNICODE_STRING_SIMPLE("script"); 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString lang_attr = UNICODE_STRING_SIMPLE("lang"); 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // test-font attributes 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name_attr = UNICODE_STRING_SIMPLE("name"); 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UXMLElement *testCase; 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t tc = 0; 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while((testCase = root->nextChildElement(tc)) != NULL) { 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (testCase->getTagName().compare(test_case) == 0) { 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *id = getCString(testCase->getAttribute(id_attr)); 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *script = getCString(testCase->getAttribute(script_attr)); 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *lang = getCString(testCase->getAttribute(lang_attr)); 19459d709d503bab6e2b61931737e662dd293b40578ccornelius ++count; 19559d709d503bab6e2b61931737e662dd293b40578ccornelius printf("\n ID %s\n", id); 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEFontInstance *font = NULL; 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UXMLElement *element; 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t ec = 0; 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t charCount = 0; 20059d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t typoFlags = LayoutEngine::kTypoFlagKern | LayoutEngine::kTypoFlagLiga; // kerning + ligatures... 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UScriptCode scriptCode; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 languageCode = -1; 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString text; 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t glyphCount = 0; 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEErrorCode leStatus = LE_NO_ERROR; 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LayoutEngine *engine = NULL; 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEGlyphID *glyphs = NULL; 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 *indices = NULL; 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float *positions = NULL; 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uscript_getCode(script, &scriptCode, 1, &status); 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("Error: invalid script name: %s.\n", script); 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto free_c_strings; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lang != NULL) { 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru languageCode = getLanguageCode(lang); 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (languageCode < 0) { 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("Error: invalid language name: %s.\n", lang); 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto free_c_strings; 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(outputFile, " <test-case id=\"%s\" script=\"%s\" lang=\"%s\">\n", id, script, lang); 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(outputFile, " <test-case id=\"%s\" script=\"%s\">\n", id, script); 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while((element = testCase->nextChildElement(ec)) != NULL) { 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString tag = element->getTagName(); 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // TODO: make sure that each element is only used once. 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (tag.compare(test_font) == 0) { 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *fontName = getCString(element->getAttribute(name_attr)); 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *version = NULL; 23759d709d503bab6e2b61931737e662dd293b40578ccornelius char buf[2048]; 23859d709d503bab6e2b61931737e662dd293b40578ccornelius PortableFontInstance *pfi = new PortableFontInstance(getPath(buf,fontName), 12, leStatus); 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(leStatus)) { 24159d709d503bab6e2b61931737e662dd293b40578ccornelius printf("Error: could not open font: %s (path: %s)\n", fontName, buf); 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru freeCString(fontName); 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto free_c_strings; 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24659d709d503bab6e2b61931737e662dd293b40578ccornelius printf(" Generating: %s, %s, %s, %s\n", id, script, lang, fontName); 24759d709d503bab6e2b61931737e662dd293b40578ccornelius 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru version = pfi->getNameString(NAME_VERSION_STRING, PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH); 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // The standard recommends that the Macintosh Roman/English name string be present, but 25185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // if it's not, try the Microsoft Unicode/English string. 25285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (version == NULL) { 25385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const LEUnicode16 *uversion = pfi->getUnicodeNameString(NAME_VERSION_STRING, PLATFORM_MICROSOFT, MICROSOFT_UNICODE_BMP, MICROSOFT_ENGLISH); 25485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 25585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (uversion != NULL) { 25659d709d503bab6e2b61931737e662dd293b40578ccornelius char uversion_utf8[300]; 25759d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode status2 = U_ZERO_ERROR; 25859d709d503bab6e2b61931737e662dd293b40578ccornelius u_strToUTF8(uversion_utf8, 300, NULL, uversion, -1, &status2); 25959d709d503bab6e2b61931737e662dd293b40578ccornelius if(U_FAILURE(status2)) { 26059d709d503bab6e2b61931737e662dd293b40578ccornelius uversion_utf8[0]=0; 26159d709d503bab6e2b61931737e662dd293b40578ccornelius } 26259d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(outputFile, " <test-font name=\"%s\" version=\"%s\" checksum=\"0x%8.8X\" rchecksum=\"0x%8.8X\"/>\n\n", 26359d709d503bab6e2b61931737e662dd293b40578ccornelius fontName, uversion_utf8, pfi->getFontChecksum(), pfi->getRawChecksum()); 26485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 26585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pfi->deleteNameString(uversion); 26659d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 26759d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(outputFile, " <test-font name=\"%s\" version=\"unknown-0x%8.8X\" checksum=\"0x%8.8X\" rchecksum=\"0x%8.8X\"/>\n\n", 26859d709d503bab6e2b61931737e662dd293b40578ccornelius fontName, pfi->getFontChecksum(), pfi->getFontChecksum(), pfi->getRawChecksum()); 26985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 27085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 27159d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(outputFile, " <test-font name=\"%s\" version=\"%s\" checksum=\"0x%8.8X\" rchecksum=\"0x%8.8X\"/>\n\n", 27259d709d503bab6e2b61931737e662dd293b40578ccornelius fontName, version, pfi->getFontChecksum(), pfi->getRawChecksum()); 27385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 27485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pfi->deleteNameString(version); 27585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 27659d709d503bab6e2b61931737e662dd293b40578ccornelius fflush(outputFile); 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru freeCString(fontName); 27985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru font = pfi; 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (tag.compare(test_text) == 0) { 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *utf8 = NULL; 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru text = element->getText(TRUE); 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru charCount = text.length(); 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru utf8 = getUTF8String(&text); 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(outputFile, " <test-text>%s</test-text>\n\n", utf8); 28959d709d503bab6e2b61931737e662dd293b40578ccornelius fflush(outputFile); 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru freeCString(utf8); 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // an unknown tag... 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *cTag = getCString(&tag); 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("Test %s: unknown element with tag \"%s\"\n", id, cTag); 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru freeCString(cTag); 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (font == NULL) { 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEErrorCode fontStatus = LE_NO_ERROR; 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru font = new SimpleFontInstance(12, fontStatus); 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru typoFlags |= 0x80000000L; // use CharSubstitutionFilter... 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru engine = LayoutEngine::layoutEngineFactory(font, scriptCode, languageCode, typoFlags, leStatus); 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(leStatus)) { 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("Error for test %s: could not create a LayoutEngine.\n", id); 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto delete_font; 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphCount = engine->layoutChars(text.getBuffer(), 0, charCount, charCount, getRTL(text), 0, 0, leStatus); 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphs = NEW_ARRAY(LEGlyphID, glyphCount); 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru indices = NEW_ARRAY(le_int32, glyphCount); 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru positions = NEW_ARRAY(float, glyphCount * 2 + 2); 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru engine->getGlyphs(glyphs, leStatus); 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru engine->getCharIndices(indices, leStatus); 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru engine->getGlyphPositions(positions, leStatus); 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 32459d709d503bab6e2b61931737e662dd293b40578ccornelius if(LE_FAILURE(leStatus)) { 32559d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(stderr,"ERROR: LO returned error: %s\n", u_errorName((UErrorCode)leStatus)); 32659d709d503bab6e2b61931737e662dd293b40578ccornelius overallStatus = leStatus; 32759d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(outputFile, "<!-- ERROR: %d -->\n", leStatus); 32859d709d503bab6e2b61931737e662dd293b40578ccornelius fflush(outputFile); 32959d709d503bab6e2b61931737e662dd293b40578ccornelius leStatus = LE_NO_ERROR; 33059d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 33159d709d503bab6e2b61931737e662dd293b40578ccornelius dumpLongs(outputFile, "result-glyphs", (le_int32 *) glyphs, glyphCount); 33259d709d503bab6e2b61931737e662dd293b40578ccornelius 33359d709d503bab6e2b61931737e662dd293b40578ccornelius dumpLongs(outputFile, "result-indices", indices, glyphCount); 33459d709d503bab6e2b61931737e662dd293b40578ccornelius 33559d709d503bab6e2b61931737e662dd293b40578ccornelius dumpFloats(outputFile, "result-positions", positions, glyphCount * 2 + 2); 33659d709d503bab6e2b61931737e662dd293b40578ccornelius fflush(outputFile); 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 33859d709d503bab6e2b61931737e662dd293b40578ccornelius } 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(positions); 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(indices); 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(glyphs); 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete engine; 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudelete_font: 34759d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(outputFile, " </test-case>\n\n"); 34859d709d503bab6e2b61931737e662dd293b40578ccornelius fflush(outputFile); 34959d709d503bab6e2b61931737e662dd293b40578ccornelius 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete font; 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufree_c_strings: 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru freeCString(lang); 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru freeCString(script); 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru freeCString(id); 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete root; 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete parser; 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(outputFile, "</layout-tests>\n"); 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 36459d709d503bab6e2b61931737e662dd293b40578ccornelius if(count==0) { 36559d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(stderr, "No cases processed!\n"); 36659d709d503bab6e2b61931737e662dd293b40578ccornelius return 1; 36759d709d503bab6e2b61931737e662dd293b40578ccornelius } 36859d709d503bab6e2b61931737e662dd293b40578ccornelius 36959d709d503bab6e2b61931737e662dd293b40578ccornelius 37059d709d503bab6e2b61931737e662dd293b40578ccornelius if(LE_FAILURE(overallStatus)) { 37159d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(outputFile, "<!-- !!! FAILED. %d -->\n", overallStatus); 37259d709d503bab6e2b61931737e662dd293b40578ccornelius fprintf(stderr, "!!! FAILED. %d\n", overallStatus); 37359d709d503bab6e2b61931737e662dd293b40578ccornelius fclose(outputFile); 37459d709d503bab6e2b61931737e662dd293b40578ccornelius return 0; 37559d709d503bab6e2b61931737e662dd293b40578ccornelius // return 1; 37659d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 37759d709d503bab6e2b61931737e662dd293b40578ccornelius printf("Generated.\n"); 37859d709d503bab6e2b61931737e662dd293b40578ccornelius fclose(outputFile); 37959d709d503bab6e2b61931737e662dd293b40578ccornelius return 0; 38059d709d503bab6e2b61931737e662dd293b40578ccornelius } 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 382