1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ********************************************************************** 350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Copyright (C) 2002-2010, International Business Machines 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Corporation and others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ********************************************************************** 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * paragraphLayout doesn't make much sense without 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * BreakIterator... 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/LETypes.h" 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/LEScripts.h" 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/LELanguages.h" 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/LayoutEngine.h" 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/LEFontInstance.h" 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ubidi.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uchriter.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/brkiter.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if ! UCONFIG_NO_BREAK_ITERATION 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "LXUtilities.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "usc_impl.h" /* this is currently private! */ 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" /* this too! */ 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "layout/ParagraphLayout.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Leave this copyright notice here! It needs to go somewhere in this library. */ 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char copyright[] = U_COPYRIGHT_STRING; 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass StyleRuns 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru StyleRuns(const RunArray *styleRunArrays[], le_int32 styleCount); 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ~StyleRuns(); 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 getRuns(le_int32 runLimits[], le_int32 styleIndices[]); 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate: 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 fStyleCount; 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 fRunCount; 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *fRunLimits; 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *fStyleIndices; 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruStyleRuns::StyleRuns(const RunArray *styleRunArrays[], le_int32 styleCount) 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : fStyleCount(styleCount), fRunCount(0), fRunLimits(NULL), fStyleIndices(NULL) 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 maxRunCount = 0; 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 style, run, runStyle; 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *currentRun = LE_NEW_ARRAY(le_int32, styleCount); 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int i = 0; i < styleCount; i += 1) { 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxRunCount += styleRunArrays[i]->getCount(); 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxRunCount -= styleCount - 1; 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunLimits = LE_NEW_ARRAY(le_int32, maxRunCount); 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleIndices = LE_NEW_ARRAY(le_int32, maxRunCount * styleCount); 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (style = 0; style < styleCount; style += 1) { 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru currentRun[style] = 0; 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru run = 0; 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runStyle = 0; 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Since the last run limit for each style run must be 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the same, all the styles will hit the last limit at 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the same time, so we know when we're done when the first 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * style hits the last limit. 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (currentRun[0] < styleRunArrays[0]->getCount()) { 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunLimits[run] = 0x7FFFFFFF; 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the minimum run limit for all the styles 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (style = 0; style < styleCount; style += 1) { 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (styleRunArrays[style]->getLimit(currentRun[style]) < fRunLimits[run]) { 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunLimits[run] = styleRunArrays[style]->getLimit(currentRun[style]); 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // advance all styles whose current run is at this limit to the next run 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (style = 0; style < styleCount; style += 1) { 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleIndices[runStyle++] = currentRun[style]; 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (styleRunArrays[style]->getLimit(currentRun[style]) == fRunLimits[run]) { 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru currentRun[style] += 1; 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru run += 1; 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunCount = run; 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(currentRun); 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruStyleRuns::~StyleRuns() 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunCount = 0; 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleIndices); 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleIndices = NULL; 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fRunLimits); 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunLimits = NULL; 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 StyleRuns::getRuns(le_int32 runLimits[], le_int32 styleIndices[]) 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (runLimits != NULL) { 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_ARRAY_COPY(runLimits, fRunLimits, fRunCount); 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (styleIndices != NULL) { 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_ARRAY_COPY(styleIndices, fStyleIndices, fRunCount * fStyleCount); 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fRunCount; 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * NOTE: This table only has "TRUE" values for 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * those scripts which the LayoutEngine can currently 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * process, rather for all scripts which require 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * complex processing for correct rendering. 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const le_bool complexTable[scriptCodeCount] = { 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE , /* Zyyy */ 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Qaai */ 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Arab */ 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Armn */ 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Beng */ 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Bopo */ 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Cher */ 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Copt=Qaac */ 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Cyrl */ 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Dsrt */ 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Deva */ 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Ethi */ 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Geor */ 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Goth */ 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Grek */ 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Gujr */ 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Guru */ 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hani */ 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hang */ 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Hebr */ 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hira */ 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Knda */ 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Kana */ 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Khmr */ 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Laoo */ 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Latn */ 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Mlym */ 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Mong */ 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Mymr */ 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Ogam */ 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Ital */ 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Orya */ 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Runr */ 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Sinh */ 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Syrc */ 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Taml */ 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Telu */ 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Thaa */ 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TRUE, /* Thai */ 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Tibt */ 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Cans */ 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Yiii */ 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Tglg */ 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hano */ 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Buhd */ 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Tagb */ 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Brai */ 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Cprt */ 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Limb */ 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Linb */ 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Osma */ 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Shaw */ 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Tale */ 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Ugar */ 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hrkt */ 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Bugi */ 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Glag */ 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Khar */ 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Sylo */ 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Talu */ 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Tfng */ 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Xpeo */ 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Bali */ 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Batk */ 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Blis */ 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Brah */ 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Cham */ 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Cirt */ 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Cyrs */ 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Egyd */ 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Egyh */ 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Egyp */ 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Geok */ 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hans */ 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hant */ 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hmng */ 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Hung */ 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Inds */ 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Java */ 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Kali */ 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Latf */ 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Latg */ 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Lepc */ 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Lina */ 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Mand */ 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Maya */ 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Mero */ 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Nkoo */ 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Orkh */ 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Perm */ 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Phag */ 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Phnx */ 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Plrd */ 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Roro */ 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Sara */ 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Syre */ 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Syrj */ 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Syrn */ 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Teng */ 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Taii */ 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Visp */ 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Xsux */ 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Zxxx */ 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Zzzz */ 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Cari */ 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Jpan */ 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Lana */ 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Lyci */ 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Lydi */ 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Olck */ 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Rjng */ 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Saur */ 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Sgnw */ 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Sund */ 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, /* Moon */ 254c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Mtei */ 255c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Armi */ 256c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Avst */ 257c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Cakm */ 258c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Kore */ 259c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Kthi */ 260c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Mani */ 261c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Phli */ 262c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Phlp */ 263c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Phlv */ 264c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Prti */ 265c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Samr */ 266c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Tavt */ 267c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru FALSE, /* Zmth */ 26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FALSE, /* Zsym */ 26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FALSE, /* Bamu */ 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FALSE, /* Lisu */ 27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FALSE, /* Nkgb */ 27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FALSE /* Sarb */ 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char ParagraphLayout::fgClassID = 0; 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27827f654740f2a26ad62a5c155af9199af9e69b889clairehostatic void fillMissingCharToGlyphMapValues(le_int32 *charToGlyphMap, 27927f654740f2a26ad62a5c155af9199af9e69b889claireho le_int32 charCount) { 28027f654740f2a26ad62a5c155af9199af9e69b889claireho le_int32 lastValidGlyph = -1; 28127f654740f2a26ad62a5c155af9199af9e69b889claireho le_int32 ch; 28227f654740f2a26ad62a5c155af9199af9e69b889claireho for (ch = 0; ch <= charCount; ch += 1) { 28327f654740f2a26ad62a5c155af9199af9e69b889claireho if (charToGlyphMap[ch] == -1) { 28427f654740f2a26ad62a5c155af9199af9e69b889claireho charToGlyphMap[ch] = lastValidGlyph; 28527f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 28627f654740f2a26ad62a5c155af9199af9e69b889claireho lastValidGlyph = charToGlyphMap[ch]; 28727f654740f2a26ad62a5c155af9199af9e69b889claireho } 28827f654740f2a26ad62a5c155af9199af9e69b889claireho } 28927f654740f2a26ad62a5c155af9199af9e69b889claireho} 29027f654740f2a26ad62a5c155af9199af9e69b889claireho 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * How to deal with composite fonts: 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Don't store the client's FontRuns; we'll need to compute sub-font FontRuns using Doug's 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * LEFontInstance method. Do that by intersecting the client's FontRuns with fScriptRuns. Use 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that to compute fFontRuns, and then intersect fFontRuns, fScriptRuns and fLevelRuns. Doing 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * it in this order means we do a two-way intersection and a three-way intersection. 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * An optimization would be to only do this if there's at least one composite font... 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Other notes: 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * * Return the sub-fonts as the run fonts... could keep the mapping back to the client's FontRuns 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * but that probably makes it more complicated of everyone... 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * * Take the LineInfo and LineRun types from Paragraph and use them here, incorporate them into the API. 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * * Might want to change the name of the StyleRun type, and make a new one that holds fonts, scripts and levels? 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count, 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const FontRuns *fontRuns, 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const ValueRuns *levelRuns, 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const ValueRuns *scriptRuns, 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LocaleRuns *localeRuns, 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel paragraphLevel, le_bool vertical, 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode &status) 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : fChars(chars), fCharCount(count), 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFontRuns(NULL), fLevelRuns(levelRuns), fScriptRuns(scriptRuns), fLocaleRuns(localeRuns), 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVertical(vertical), fClientLevels(TRUE), fClientScripts(TRUE), fClientLocales(TRUE), fEmbeddingLevels(NULL), 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAscent(0), fDescent(0), fLeading(0), 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphToCharMap(NULL), fCharToMinGlyphMap(NULL), fCharToMaxGlyphMap(NULL), fGlyphWidths(NULL), fGlyphCount(0), 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fParaBidi(NULL), fLineBidi(NULL), 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunLimits(NULL), fStyleIndices(NULL), fStyleRunCount(0), 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fBreakIterator(NULL), fLineStart(-1), fLineEnd(0), 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*fVisualRuns(NULL), fStyleRunInfo(NULL), fVisualRunCount(-1), 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstVisualRun(-1), fLastVisualRun(-1),*/ fVisualRunLastX(0), fVisualRunLastY(0) 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharCount = -1; 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // FIXME: should check the limit arrays for consistency... 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeLevels(paragraphLevel); 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (scriptRuns == NULL) { 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeScripts(); 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (localeRuns == NULL) { 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeLocales(); 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeSubFonts(fontRuns, status); 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //other stuff? 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharCount = -1; 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now intersect the font, direction and script runs... 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const RunArray *styleRunArrays[] = {fFontRuns, fLevelRuns, fScriptRuns, fLocaleRuns}; 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0]; 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru StyleRuns styleRuns(styleRunArrays, styleCount); 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode layoutStatus = LE_NO_ERROR; 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunCount = styleRuns.getRuns(NULL, NULL); 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunLimits = LE_NEW_ARRAY(le_int32, fStyleRunCount); 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleIndices = LE_NEW_ARRAY(le_int32, fStyleRunCount * styleCount); 365b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((fStyleRunLimits == NULL) || (fStyleIndices == NULL)) { 366b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = LE_MEMORY_ALLOCATION_ERROR; 367b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 368b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 369b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru styleRuns.getRuns(fStyleRunLimits, fStyleIndices); 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now build a LayoutEngine for each style run... 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *styleIndices = fStyleIndices; 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run, runStart; 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo = LE_NEW_ARRAY(StyleRunInfo, fStyleRunCount); 377b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (fStyleRunInfo == NULL) { 378b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = LE_MEMORY_ALLOCATION_ERROR; 379b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 380b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 381b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else { 382b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // initialize 383b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) { 384b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].font = NULL; 385b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].runBase = 0; 386b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].runLimit = 0; 387b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].script = (UScriptCode)0; 388b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].locale = NULL; 389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].level = 0; 390b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].glyphBase = 0; 391b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].engine = NULL; 392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].glyphCount = 0; 393b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].glyphs = NULL; 394b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].positions = NULL; 395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphCount = 0; 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) { 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].font = fFontRuns->getFont(styleIndices[0]); 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].runBase = runStart; 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].runLimit = fStyleRunLimits[run]; 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].script = (UScriptCode) fScriptRuns->getValue(styleIndices[2]); 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].locale = fLocaleRuns->getLocale(styleIndices[3]); 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].level = (UBiDiLevel) fLevelRuns->getValue(styleIndices[1]); 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].glyphBase = fGlyphCount; 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].engine = LayoutEngine::layoutEngineFactory(fStyleRunInfo[run].font, 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].script, getLanguageCode(fStyleRunInfo[run].locale), layoutStatus); 410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].glyphCount = fStyleRunInfo[run].engine->layoutChars(fChars, runStart, fStyleRunLimits[run] - runStart, fCharCount, 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].level & 1, 0, 0, layoutStatus); 417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runStart = fStyleRunLimits[run]; 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru styleIndices += styleCount; 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphCount += fStyleRunInfo[run].glyphCount; 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Make big arrays for the glyph widths, glyph-to-char and char-to-glyph maps, 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in logical order. (Both maps need an extra entry for the end of the text.) 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // For each layout get the positions and convert them into glyph widths, in 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // logical order. Get the glyph-to-char mapping, offset by starting index in the 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // character array. Swap the glyph width and glyph-to-char arrays into logical order. 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Finally, fill in the char-to-glyph mappings. 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphWidths = LE_NEW_ARRAY(float, fGlyphCount); 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphToCharMap = LE_NEW_ARRAY(le_int32, fGlyphCount + 1); 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMinGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1); 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMaxGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1); 438b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((fGlyphWidths == NULL) || (fGlyphToCharMap == NULL) || 439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (fCharToMinGlyphMap == NULL) || (fCharToMaxGlyphMap == NULL)) { 440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = LE_MEMORY_ALLOCATION_ERROR; 441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyph; 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) { 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LayoutEngine *engine = fStyleRunInfo[run].engine; 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount = fStyleRunInfo[run].glyphCount; 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphBase = fStyleRunInfo[run].glyphBase; 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount); 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].positions = LE_NEW_ARRAY(float, glyphCount * 2 + 2); 453b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((fStyleRunInfo[run].glyphs == NULL) || 454b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (fStyleRunInfo[run].positions == NULL)) { 455b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = LE_MEMORY_ALLOCATION_ERROR; 456b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 457b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(fStyleRunInfo[run].glyphs, layoutStatus); 460b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 461b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 462b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 463b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 464b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPositions(fStyleRunInfo[run].positions, layoutStatus); 466b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 467b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 468b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 469b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 470b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(&fGlyphToCharMap[glyphBase], runStart, layoutStatus); 472b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 473b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 474b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 475b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (glyph = 0; glyph < glyphCount; glyph += 1) { 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphWidths[glyphBase + glyph] = fStyleRunInfo[run].positions[glyph * 2 + 2] - fStyleRunInfo[run].positions[glyph * 2]; 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fStyleRunInfo[run].level & 1) != 0) { 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LXUtilities::reverse(&fGlyphWidths[glyphBase], glyphCount); 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LXUtilities::reverse(&fGlyphToCharMap[glyphBase], glyphCount); 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runStart = fStyleRunLimits[run]; 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete engine; 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].engine = NULL; 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphToCharMap[fGlyphCount] = fCharCount; 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49427f654740f2a26ad62a5c155af9199af9e69b889claireho // Initialize the char-to-glyph maps to -1 so that we can later figure out 49527f654740f2a26ad62a5c155af9199af9e69b889claireho // whether any of the entries in the map aren't filled in below. 49627f654740f2a26ad62a5c155af9199af9e69b889claireho le_int32 chIndex; 49727f654740f2a26ad62a5c155af9199af9e69b889claireho for (chIndex = 0; chIndex <= fCharCount; chIndex += 1) { 49827f654740f2a26ad62a5c155af9199af9e69b889claireho fCharToMinGlyphMap[chIndex] = -1; 49927f654740f2a26ad62a5c155af9199af9e69b889claireho fCharToMaxGlyphMap[chIndex] = -1; 50027f654740f2a26ad62a5c155af9199af9e69b889claireho } 50127f654740f2a26ad62a5c155af9199af9e69b889claireho 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (glyph = fGlyphCount - 1; glyph >= 0; glyph -= 1) { 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ch = fGlyphToCharMap[glyph]; 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMinGlyphMap[ch] = glyph; 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMinGlyphMap[fCharCount] = fGlyphCount; 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (glyph = 0; glyph < fGlyphCount; glyph += 1) { 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ch = fGlyphToCharMap[glyph]; 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMaxGlyphMap[ch] = glyph; 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMaxGlyphMap[fCharCount] = fGlyphCount; 51727f654740f2a26ad62a5c155af9199af9e69b889claireho 51827f654740f2a26ad62a5c155af9199af9e69b889claireho // Now fill in the missing values in the char-to-glyph maps. 51927f654740f2a26ad62a5c155af9199af9e69b889claireho fillMissingCharToGlyphMapValues(fCharToMinGlyphMap, fCharCount); 52027f654740f2a26ad62a5c155af9199af9e69b889claireho fillMissingCharToGlyphMapValues(fCharToMaxGlyphMap, fCharCount); 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::~ParagraphLayout() 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (FontRuns *) fFontRuns; 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (! fClientLevels) { 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (ValueRuns *) fLevelRuns; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLevelRuns = NULL; 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientLevels = TRUE; 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (! fClientScripts) { 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (ValueRuns *) fScriptRuns; 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fScriptRuns = NULL; 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientScripts = TRUE; 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (! fClientLocales) { 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (LocaleRuns *) fLocaleRuns; 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLocaleRuns = NULL; 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientLocales = TRUE; 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fEmbeddingLevels != NULL) { 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fEmbeddingLevels); 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fEmbeddingLevels = NULL; 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fGlyphToCharMap != NULL) { 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fGlyphToCharMap); 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphToCharMap = NULL; 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fCharToMinGlyphMap != NULL) { 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fCharToMinGlyphMap); 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMinGlyphMap = NULL; 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fCharToMaxGlyphMap != NULL) { 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fCharToMaxGlyphMap); 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMaxGlyphMap = NULL; 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fGlyphWidths != NULL) { 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fGlyphWidths); 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphWidths = NULL; 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fParaBidi != NULL) { 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_close(fParaBidi); 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fParaBidi = NULL; 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fLineBidi != NULL) { 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_close(fLineBidi); 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineBidi = NULL; 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fStyleRunCount > 0) { 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run; 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleRunLimits); 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleIndices); 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (run = 0; run < fStyleRunCount; run += 1) { 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleRunInfo[run].glyphs); 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleRunInfo[run].positions); 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].glyphs = NULL; 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].positions = NULL; 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleRunInfo); 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunLimits = NULL; 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleIndices = NULL; 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo = NULL; 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunCount = 0; 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fBreakIterator != NULL) { 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete fBreakIterator; 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fBreakIterator = NULL; 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_bool ParagraphLayout::isComplex(const LEUnicode chars[], le_int32 count) 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode scriptStatus = U_ZERO_ERROR; 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptCode scriptCode = USCRIPT_INVALID_CODE; 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptRun *sr = uscript_openRun(chars, count, &scriptStatus); 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_bool result = FALSE; 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (uscript_nextRun(sr, NULL, NULL, &scriptCode)) { 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isComplex(scriptCode)) { 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = TRUE; 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uscript_closeRun(sr); 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getAscent() const 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0 && fCharCount > 0) { 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout *) this)->computeMetrics(); 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fAscent; 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getDescent() const 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0 && fCharCount > 0) { 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout *) this)->computeMetrics(); 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fDescent; 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getLeading() const 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0 && fCharCount > 0) { 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout *) this)->computeMetrics(); 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fLeading; 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 65750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehole_bool ParagraphLayout::isDone() const 65850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 65950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return fLineEnd >= fCharCount; 66050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 66150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::Line *ParagraphLayout::nextLine(float width) 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 66450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (isDone()) { 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineStart = fLineEnd; 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (width > 0) { 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyph = fCharToMinGlyphMap[fLineStart]; 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float widthSoFar = 0; 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (glyph < fGlyphCount && widthSoFar + fGlyphWidths[glyph] <= width) { 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru widthSoFar += fGlyphWidths[glyph++]; 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If no glyphs fit on the line, force one to fit. 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (There shouldn't be any zero width glyphs at the 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // start of a line unless the paragraph consists of 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // only zero width glyphs, because otherwise the zero 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // width glyphs will have been included on the end of 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the previous line...) 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (widthSoFar == 0 && glyph < fGlyphCount) { 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyph += 1; 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineEnd = previousBreak(fGlyphToCharMap[glyph]); 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If this break is at or before the last one, 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find a glyph, starting at the one which didn't 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fit, that produces a break after the last one. 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (fLineEnd <= fLineStart) { 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineEnd = fGlyphToCharMap[glyph++]; 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineEnd = fCharCount; 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return computeVisualRuns(); 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeLevels(UBiDiLevel paragraphLevel) 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode bidiStatus = U_ZERO_ERROR; 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fLevelRuns != NULL) { 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ch; 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run; 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fEmbeddingLevels = LE_NEW_ARRAY(UBiDiLevel, fCharCount); 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (ch = 0, run = 0; run < fLevelRuns->getCount(); run += 1) { 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel runLevel = (UBiDiLevel) fLevelRuns->getValue(run) | UBIDI_LEVEL_OVERRIDE; 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 runLimit = fLevelRuns->getLimit(run); 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (ch < runLimit) { 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fEmbeddingLevels[ch++] = runLevel; 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fParaBidi = ubidi_openSized(fCharCount, 0, &bidiStatus); 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_setPara(fParaBidi, fChars, fCharCount, paragraphLevel, fEmbeddingLevels, &bidiStatus); 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fLevelRuns == NULL) { 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 levelRunCount = ubidi_countRuns(fParaBidi, &bidiStatus); 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ValueRuns *levelRuns = new ValueRuns(levelRunCount); 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 logicalStart = 0; 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run; 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 limit; 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel level; 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (run = 0; run < levelRunCount; run += 1) { 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_getLogicalRun(fParaBidi, logicalStart, &limit, &level); 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru levelRuns->add(level, limit); 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart = limit; 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLevelRuns = levelRuns; 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientLevels = FALSE; 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeScripts() 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode scriptStatus = U_ZERO_ERROR; 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptRun *sr = uscript_openRun(fChars, fCharCount, &scriptStatus); 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ValueRuns *scriptRuns = new ValueRuns(0); 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 limit; 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptCode script; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (uscript_nextRun(sr, NULL, &limit, &script)) { 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru scriptRuns->add(script, limit); 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uscript_closeRun(sr); 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fScriptRuns = scriptRuns; 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientScripts = FALSE; 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeLocales() 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LocaleRuns *localeRuns = new LocaleRuns(0); 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Locale *defaultLocale = &Locale::getDefault(); 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeRuns->add(defaultLocale, fCharCount); 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLocaleRuns = localeRuns; 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientLocales = FALSE; 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status) 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const RunArray *styleRunArrays[] = {fontRuns, fScriptRuns}; 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0]; 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru StyleRuns styleRuns(styleRunArrays, styleCount); 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 styleRunCount = styleRuns.getRuns(NULL, NULL); 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *styleRunLimits = LE_NEW_ARRAY(le_int32, styleRunCount); 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *styleIndices = LE_NEW_ARRAY(le_int32, styleRunCount * styleCount); 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FontRuns *subFontRuns = new FontRuns(0); 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run, offset, *si; 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru styleRuns.getRuns(styleRunLimits, styleIndices); 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru si = styleIndices; 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = 0; 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (run = 0; run < styleRunCount; run += 1) { 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LEFontInstance *runFont = fontRuns->getFont(si[0]); 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 script = fScriptRuns->getValue(si[1]); 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (offset < styleRunLimits[run]) { 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LEFontInstance *subFont = runFont->getSubFont(fChars, &offset, styleRunLimits[run], script, status); 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete subFontRuns; 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanUp; 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subFontRuns->add(subFont, offset); 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru si += styleCount; 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFontRuns = subFontRuns; 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucleanUp: 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(styleIndices); 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(styleRunLimits); 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeMetrics() 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 i, count = fFontRuns->getCount(); 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 maxDL = 0; 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < count; i += 1) { 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LEFontInstance *font = fFontRuns->getFont(i); 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ascent = font->getAscent(); 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 descent = font->getDescent(); 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 leading = font->getLeading(); 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 dl = descent + leading; 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ascent > fAscent) { 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAscent = ascent; 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (descent > fDescent) { 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fDescent = descent; 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (leading > fLeading) { 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLeading = leading; 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dl > maxDL) { 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxDL = dl; 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLeading = maxDL - fDescent; 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 1 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct LanguageMap 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *localeCode; 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 languageCode; 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const LanguageMap languageMap[] = 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 862c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"afr", afkLanguageCode}, // Afrikaans 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ara", araLanguageCode}, // Arabic 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"asm", asmLanguageCode}, // Assamese 865c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"bel", belLanguageCode}, // Belarussian 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ben", benLanguageCode}, // Bengali 867c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"bod", tibLanguageCode}, // Tibetan 868c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"bul", bgrLanguageCode}, // Bulgarian 869c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"cat", catLanguageCode}, // Catalan 870c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ces", csyLanguageCode}, // Czech 871c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"che", cheLanguageCode}, // Chechen 872c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"cop", copLanguageCode}, // Coptic 873c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"cym", welLanguageCode}, // Welsh 874c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"dan", danLanguageCode}, // Danish 875c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"deu", deuLanguageCode}, // German 876c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"dzo", dznLanguageCode}, // Dzongkha 877c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ell", ellLanguageCode}, // Greek 878c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"eng", engLanguageCode}, // English 879c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"est", etiLanguageCode}, // Estonian 880c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"eus", euqLanguageCode}, // Basque 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"fas", farLanguageCode}, // Farsi 882c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"fin", finLanguageCode}, // Finnish 883c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"fra", fraLanguageCode}, // French 884c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"gle", gaeLanguageCode}, // Irish Gaelic 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"guj", gujLanguageCode}, // Gujarati 886c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"hau", hauLanguageCode}, // Hausa 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"heb", iwrLanguageCode}, // Hebrew 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"hin", hinLanguageCode}, // Hindi 889c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"hrv", hrvLanguageCode}, // Croatian 890c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"hun", hunLanguageCode}, // Hungarian 891c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"hye", hyeLanguageCode}, // Armenian 892c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ind", indLanguageCode}, // Indonesian 893c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ita", itaLanguageCode}, // Italian 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"jpn", janLanguageCode}, // Japanese 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"kan", kanLanguageCode}, // Kannada 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"kas", kshLanguageCode}, // Kashmiri 897c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"khm", khmLanguageCode}, // Khmer 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"kok", kokLanguageCode}, // Konkani 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"kor", korLanguageCode}, // Korean 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// {"mal_XXX", malLanguageCode}, // Malayalam - Traditional 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"mal", mlrLanguageCode}, // Malayalam - Reformed 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"mar", marLanguageCode}, // Marathi 903c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"mlt", mtsLanguageCode}, // Maltese 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"mni", mniLanguageCode}, // Manipuri 905c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"mon", mngLanguageCode}, // Mongolian 906c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"nep", nepLanguageCode}, // Nepali 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ori", oriLanguageCode}, // Oriya 908c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"pol", plkLanguageCode}, // Polish 909c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"por", ptgLanguageCode}, // Portuguese 910c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"pus", pasLanguageCode}, // Pashto 911c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ron", romLanguageCode}, // Romanian 912c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"rus", rusLanguageCode}, // Russian 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"san", sanLanguageCode}, // Sanskrit 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"sin", snhLanguageCode}, // Sinhalese 915c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"slk", skyLanguageCode}, // Slovak 916c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"snd", sndLanguageCode}, // Sindhi 917c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"slv", slvLanguageCode}, // Slovenian 918c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"spa", espLanguageCode}, // Spanish 919c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"sqi", sqiLanguageCode}, // Albanian 920c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"srp", srbLanguageCode}, // Serbian 921c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"swe", sveLanguageCode}, // Swedish 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"syr", syrLanguageCode}, // Syriac 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"tam", tamLanguageCode}, // Tamil 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"tel", telLanguageCode}, // Telugu 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"tha", thaLanguageCode}, // Thai 926c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"tur", trkLanguageCode}, // Turkish 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"urd", urdLanguageCode}, // Urdu 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"yid", jiiLanguageCode}, // Yiddish 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// {"zhp", zhpLanguageCode}, // Chinese - Phonetic 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho", zhsLanguageCode}, // Chinese 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_CHN", zhsLanguageCode}, // Chinese - China 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_HKG", zhsLanguageCode}, // Chinese - Hong Kong 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_MAC", zhtLanguageCode}, // Chinese - Macao 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_SGP", zhsLanguageCode}, // Chinese - Singapore 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_TWN", zhtLanguageCode} // Chinese - Taiwan 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const le_int32 languageMapCount = ARRAY_SIZE(languageMap); 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getLanguageCode(const Locale *locale) 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char code[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *language = locale->getISO3Language(); 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *country = locale->getISO3Country(); 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(code, language); 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((uprv_strcmp(language, "zho") == 0) && country != NULL) { 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(code, "_"); 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(code, country); 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (le_int32 i = 0; i < languageMapCount; i += 1) { 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(code, languageMap[i].localeCode) == 0) { 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return languageMap[i].languageCode; 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return nullLanguageCode; 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 961b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#else 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// TODO - dummy implementation for right now... 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getLanguageCode(const Locale *locale) 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return nullLanguageCode; 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_bool ParagraphLayout::isComplex(UScriptCode script) 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (script < 0 || script >= (UScriptCode) scriptCodeCount) { 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return complexTable[script]; 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::previousBreak(le_int32 charIndex) 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // skip over any whitespace or control characters, 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // because they can hang in the margin. 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (charIndex < fCharCount && 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (u_isWhitespace(fChars[charIndex]) || 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_iscntrl(fChars[charIndex]))) { 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charIndex += 1; 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create the BreakIterator if we don't already have one 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fBreakIterator == NULL) { 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale thai("th"); 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCharCharacterIterator *iter = new UCharCharacterIterator(fChars, fCharCount); 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fBreakIterator = BreakIterator::createLineInstance(thai, status); 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fBreakIterator->adoptText(iter); 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // return the break location that's at or before 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the character we stopped on. Note: if we're 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // on a break, the "+ 1" will cause preceding to 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // back up to it. 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fBreakIterator->preceding(charIndex + 1); 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::Line *ParagraphLayout::computeVisualRuns() 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode bidiStatus = U_ZERO_ERROR; 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 dirRunCount, visualRun; 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVisualRunLastX = 0; 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVisualRunLastY = 0; 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstVisualRun = getCharRun(fLineStart); 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLastVisualRun = getCharRun(fLineEnd - 1); 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fLineBidi == NULL) { 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineBidi = ubidi_openSized(fCharCount, 0, &bidiStatus); 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_setLine(fParaBidi, fLineStart, fLineEnd, fLineBidi, &bidiStatus); 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dirRunCount = ubidi_countRuns(fLineBidi, &bidiStatus); 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Line *line = new Line(); 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (visualRun = 0; visualRun < dirRunCount; visualRun += 1) { 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 relStart, run, runLength; 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiDirection runDirection = ubidi_getVisualRun(fLineBidi, visualRun, &relStart, &runLength); 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 runStart = fLineStart + relStart; 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 runEnd = runStart + runLength - 1; 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 firstRun = getCharRun(runStart); 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 lastRun = getCharRun(runEnd); 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 startRun = (runDirection == UBIDI_LTR)? firstRun : lastRun; 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 stopRun = (runDirection == UBIDI_LTR)? lastRun + 1 : firstRun - 1; 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 dir = (runDirection == UBIDI_LTR)? 1 : -1; 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (run = startRun; run != stopRun; run += dir) { 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 firstChar = (run == firstRun)? runStart : fStyleRunInfo[run].runBase; 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 lastChar = (run == lastRun)? runEnd : fStyleRunInfo[run].runLimit - 1; 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru appendRun(line, run, firstChar, lastChar); 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return line; 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::appendRun(ParagraphLayout::Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar) 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphBase = fStyleRunInfo[run].glyphBase; 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 inGlyph, outGlyph; 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the glyph indices for all the characters between firstChar and lastChar, 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // make the minimum one be leftGlyph and the maximum one be rightGlyph. 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (need to do this to handle local reorderings like Indic left matras) 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 leftGlyph = fGlyphCount; 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 rightGlyph = -1; 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ch; 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (ch = firstChar; ch <= lastChar; ch += 1) { 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 minGlyph = fCharToMinGlyphMap[ch]; 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 maxGlyph = fCharToMaxGlyphMap[ch]; 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (minGlyph < leftGlyph) { 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leftGlyph = minGlyph; 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (maxGlyph > rightGlyph) { 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightGlyph = maxGlyph; 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fStyleRunInfo[run].level & 1) != 0) { 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 swap = rightGlyph; 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 last = glyphBase + fStyleRunInfo[run].glyphCount - 1; 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Here, we want to remove the glyphBase bias... 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightGlyph = last - leftGlyph; 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leftGlyph = last - swap; 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightGlyph -= glyphBase; 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leftGlyph -= glyphBase; 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set the position bias for the glyphs. If we're at the start of 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // a line, we want the first glyph to be at x = 0, even if it comes 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // from the middle of a layout. If we've got a right-to-left run, we 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // want the left-most glyph to start at the final x position of the 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // previous run, even though this glyph may be in the middle of the 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // run. 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVisualRunLastX -= fStyleRunInfo[run].positions[leftGlyph * 2]; 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Make rightGlyph be the glyph just to the right of 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the run's glyphs 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightGlyph += 1; 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiDirection direction = ((fStyleRunInfo[run].level & 1) == 0)? UBIDI_LTR : UBIDI_RTL; 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount = rightGlyph - leftGlyph; 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEGlyphID *glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount); 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float *positions = LE_NEW_ARRAY(float, glyphCount * 2 + 2); 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *glyphToCharMap = LE_NEW_ARRAY(le_int32, glyphCount); 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_ARRAY_COPY(glyphs, &fStyleRunInfo[run].glyphs[leftGlyph], glyphCount); 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (outGlyph = 0, inGlyph = leftGlyph * 2; inGlyph <= rightGlyph * 2; inGlyph += 2, outGlyph += 2) { 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru positions[outGlyph] = fStyleRunInfo[run].positions[inGlyph] + fVisualRunLastX; 110650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho positions[outGlyph + 1] = fStyleRunInfo[run].positions[inGlyph + 1] + fVisualRunLastY; 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save the ending position of this run 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to use for the start of the next run 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVisualRunLastX = positions[outGlyph - 2]; 111250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fVisualRunLastY = positions[outGlyph - 1]; 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fStyleRunInfo[run].level & 1) == 0) { 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (outGlyph = 0, inGlyph = leftGlyph; inGlyph < rightGlyph; inGlyph += 1, outGlyph += 1) { 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphToCharMap[outGlyph] = fGlyphToCharMap[glyphBase + inGlyph]; 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Because fGlyphToCharMap is stored in logical order to facilitate line breaking, 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we need to map the physical glyph indices to logical indices while we copy the 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // character indices. 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 base = glyphBase + fStyleRunInfo[run].glyphCount - 1; 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (outGlyph = 0, inGlyph = leftGlyph; inGlyph < rightGlyph; inGlyph += 1, outGlyph += 1) { 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphToCharMap[outGlyph] = fGlyphToCharMap[base - inGlyph]; 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru line->append(fStyleRunInfo[run].font, direction, glyphCount, glyphs, positions, glyphToCharMap); 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getCharRun(le_int32 charIndex) 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (charIndex < 0 || charIndex > fCharCount) { 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run; 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // NOTE: as long as fStyleRunLimits is well-formed 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the above range check guarantees that we'll never 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fall off the end of the array. 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru run = 0; 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (charIndex >= fStyleRunLimits[run]) { 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru run += 1; 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return run; 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char ParagraphLayout::Line::fgClassID = 0; 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define INITIAL_RUN_CAPACITY 4 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RUN_CAPACITY_GROW_LIMIT 16 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::Line::~Line() 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 i; 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < fRunCount; i += 1) { 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete fRuns[i]; 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fRuns); 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::Line::getAscent() const 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0) { 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout::Line *)this)->computeMetrics(); 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fAscent; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::Line::getDescent() const 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0) { 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout::Line *)this)->computeMetrics(); 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fDescent; 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::Line::getLeading() const 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0) { 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout::Line *)this)->computeMetrics(); 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fLeading; 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::Line::getWidth() const 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const VisualRun *lastRun = getVisualRun(fRunCount - 1); 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lastRun == NULL) { 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount = lastRun->getGlyphCount(); 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const float *positions = lastRun->getPositions(); 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (le_int32) positions[glyphCount * 2]; 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst ParagraphLayout::VisualRun *ParagraphLayout::Line::getVisualRun(le_int32 runIndex) const 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (runIndex < 0 || runIndex >= fRunCount) { 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fRuns[runIndex]; 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::Line::append(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount, 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]) 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fRunCount >= fRunCapacity) { 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fRunCapacity == 0) { 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunCapacity = INITIAL_RUN_CAPACITY; 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRuns = LE_NEW_ARRAY(ParagraphLayout::VisualRun *, fRunCapacity); 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunCapacity += (fRunCapacity < RUN_CAPACITY_GROW_LIMIT? fRunCapacity : RUN_CAPACITY_GROW_LIMIT); 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRuns = (ParagraphLayout::VisualRun **) LE_GROW_ARRAY(fRuns, fRunCapacity); 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRuns[fRunCount++] = new ParagraphLayout::VisualRun(font, direction, glyphCount, glyphs, positions, glyphToCharMap); 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::Line::computeMetrics() 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 maxDL = 0; 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (le_int32 i = 0; i < fRunCount; i += 1) { 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ascent = fRuns[i]->getAscent(); 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 descent = fRuns[i]->getDescent(); 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 leading = fRuns[i]->getLeading(); 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 dl = descent + leading; 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ascent > fAscent) { 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAscent = ascent; 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (descent > fDescent) { 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fDescent = descent; 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (leading > fLeading) { 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLeading = leading; 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dl > maxDL) { 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxDL = dl; 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLeading = maxDL - fDescent; 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char ParagraphLayout::VisualRun::fgClassID = 0; 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::VisualRun::~VisualRun() 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fGlyphToCharMap); 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fPositions); 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fGlyphs); 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1277