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 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * How to deal with composite fonts: 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Don't store the client's FontRuns; we'll need to compute sub-font FontRuns using Doug's 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * LEFontInstance method. Do that by intersecting the client's FontRuns with fScriptRuns. Use 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that to compute fFontRuns, and then intersect fFontRuns, fScriptRuns and fLevelRuns. Doing 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * it in this order means we do a two-way intersection and a three-way intersection. 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * An optimization would be to only do this if there's at least one composite font... 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Other notes: 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * * Return the sub-fonts as the run fonts... could keep the mapping back to the client's FontRuns 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * but that probably makes it more complicated of everyone... 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * * Take the LineInfo and LineRun types from Paragraph and use them here, incorporate them into the API. 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * * Might want to change the name of the StyleRun type, and make a new one that holds fonts, scripts and levels? 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count, 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const FontRuns *fontRuns, 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const ValueRuns *levelRuns, 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const ValueRuns *scriptRuns, 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LocaleRuns *localeRuns, 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel paragraphLevel, le_bool vertical, 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode &status) 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : fChars(chars), fCharCount(count), 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFontRuns(NULL), fLevelRuns(levelRuns), fScriptRuns(scriptRuns), fLocaleRuns(localeRuns), 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVertical(vertical), fClientLevels(TRUE), fClientScripts(TRUE), fClientLocales(TRUE), fEmbeddingLevels(NULL), 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAscent(0), fDescent(0), fLeading(0), 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphToCharMap(NULL), fCharToMinGlyphMap(NULL), fCharToMaxGlyphMap(NULL), fGlyphWidths(NULL), fGlyphCount(0), 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fParaBidi(NULL), fLineBidi(NULL), 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunLimits(NULL), fStyleIndices(NULL), fStyleRunCount(0), 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fBreakIterator(NULL), fLineStart(-1), fLineEnd(0), 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*fVisualRuns(NULL), fStyleRunInfo(NULL), fVisualRunCount(-1), 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstVisualRun(-1), fLastVisualRun(-1),*/ fVisualRunLastX(0), fVisualRunLastY(0) 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharCount = -1; 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // FIXME: should check the limit arrays for consistency... 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeLevels(paragraphLevel); 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (scriptRuns == NULL) { 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeScripts(); 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (localeRuns == NULL) { 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeLocales(); 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeSubFonts(fontRuns, status); 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //other stuff? 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharCount = -1; 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now intersect the font, direction and script runs... 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const RunArray *styleRunArrays[] = {fFontRuns, fLevelRuns, fScriptRuns, fLocaleRuns}; 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0]; 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru StyleRuns styleRuns(styleRunArrays, styleCount); 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEErrorCode layoutStatus = LE_NO_ERROR; 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunCount = styleRuns.getRuns(NULL, NULL); 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunLimits = LE_NEW_ARRAY(le_int32, fStyleRunCount); 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleIndices = LE_NEW_ARRAY(le_int32, fStyleRunCount * styleCount); 352b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((fStyleRunLimits == NULL) || (fStyleIndices == NULL)) { 353b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = LE_MEMORY_ALLOCATION_ERROR; 354b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 355b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 356b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru styleRuns.getRuns(fStyleRunLimits, fStyleIndices); 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now build a LayoutEngine for each style run... 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *styleIndices = fStyleIndices; 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run, runStart; 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo = LE_NEW_ARRAY(StyleRunInfo, fStyleRunCount); 364b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (fStyleRunInfo == NULL) { 365b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = LE_MEMORY_ALLOCATION_ERROR; 366b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 367b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 368b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else { 369b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // initialize 370b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) { 371b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].font = NULL; 372b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].runBase = 0; 373b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].runLimit = 0; 374b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].script = (UScriptCode)0; 375b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].locale = NULL; 376b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].level = 0; 377b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].glyphBase = 0; 378b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].engine = NULL; 379b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].glyphCount = 0; 380b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].glyphs = NULL; 381b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fStyleRunInfo[run].positions = NULL; 382b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 383b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphCount = 0; 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) { 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].font = fFontRuns->getFont(styleIndices[0]); 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].runBase = runStart; 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].runLimit = fStyleRunLimits[run]; 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].script = (UScriptCode) fScriptRuns->getValue(styleIndices[2]); 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].locale = fLocaleRuns->getLocale(styleIndices[3]); 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].level = (UBiDiLevel) fLevelRuns->getValue(styleIndices[1]); 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].glyphBase = fGlyphCount; 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].engine = LayoutEngine::layoutEngineFactory(fStyleRunInfo[run].font, 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].script, getLanguageCode(fStyleRunInfo[run].locale), layoutStatus); 397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 400b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].glyphCount = fStyleRunInfo[run].engine->layoutChars(fChars, runStart, fStyleRunLimits[run] - runStart, fCharCount, 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].level & 1, 0, 0, layoutStatus); 404b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runStart = fStyleRunLimits[run]; 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru styleIndices += styleCount; 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphCount += fStyleRunInfo[run].glyphCount; 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Make big arrays for the glyph widths, glyph-to-char and char-to-glyph maps, 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in logical order. (Both maps need an extra entry for the end of the text.) 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // For each layout get the positions and convert them into glyph widths, in 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // logical order. Get the glyph-to-char mapping, offset by starting index in the 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // character array. Swap the glyph width and glyph-to-char arrays into logical order. 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Finally, fill in the char-to-glyph mappings. 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphWidths = LE_NEW_ARRAY(float, fGlyphCount); 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphToCharMap = LE_NEW_ARRAY(le_int32, fGlyphCount + 1); 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMinGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1); 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMaxGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1); 425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((fGlyphWidths == NULL) || (fGlyphToCharMap == NULL) || 426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (fCharToMinGlyphMap == NULL) || (fCharToMaxGlyphMap == NULL)) { 427b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = LE_MEMORY_ALLOCATION_ERROR; 428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyph; 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) { 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LayoutEngine *engine = fStyleRunInfo[run].engine; 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount = fStyleRunInfo[run].glyphCount; 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphBase = fStyleRunInfo[run].glyphBase; 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount); 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].positions = LE_NEW_ARRAY(float, glyphCount * 2 + 2); 440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((fStyleRunInfo[run].glyphs == NULL) || 441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (fStyleRunInfo[run].positions == NULL)) { 442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = LE_MEMORY_ALLOCATION_ERROR; 443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphs(fStyleRunInfo[run].glyphs, layoutStatus); 447b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 448b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 449b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 450b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 451b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getGlyphPositions(fStyleRunInfo[run].positions, layoutStatus); 453b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 454b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 455b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 456b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 457b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru engine->getCharIndices(&fGlyphToCharMap[glyphBase], runStart, layoutStatus); 459b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (LE_FAILURE(layoutStatus)) { 460b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru status = layoutStatus; 461b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 462b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (glyph = 0; glyph < glyphCount; glyph += 1) { 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphWidths[glyphBase + glyph] = fStyleRunInfo[run].positions[glyph * 2 + 2] - fStyleRunInfo[run].positions[glyph * 2]; 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fStyleRunInfo[run].level & 1) != 0) { 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LXUtilities::reverse(&fGlyphWidths[glyphBase], glyphCount); 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LXUtilities::reverse(&fGlyphToCharMap[glyphBase], glyphCount); 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runStart = fStyleRunLimits[run]; 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete engine; 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].engine = NULL; 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphToCharMap[fGlyphCount] = fCharCount; 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (glyph = fGlyphCount - 1; glyph >= 0; glyph -= 1) { 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ch = fGlyphToCharMap[glyph]; 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMinGlyphMap[ch] = glyph; 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMinGlyphMap[fCharCount] = fGlyphCount; 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (glyph = 0; glyph < fGlyphCount; glyph += 1) { 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ch = fGlyphToCharMap[glyph]; 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMaxGlyphMap[ch] = glyph; 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMaxGlyphMap[fCharCount] = fGlyphCount; 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::~ParagraphLayout() 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (FontRuns *) fFontRuns; 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (! fClientLevels) { 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (ValueRuns *) fLevelRuns; 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLevelRuns = NULL; 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientLevels = TRUE; 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (! fClientScripts) { 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (ValueRuns *) fScriptRuns; 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fScriptRuns = NULL; 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientScripts = TRUE; 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (! fClientLocales) { 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (LocaleRuns *) fLocaleRuns; 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLocaleRuns = NULL; 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientLocales = TRUE; 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fEmbeddingLevels != NULL) { 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fEmbeddingLevels); 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fEmbeddingLevels = NULL; 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fGlyphToCharMap != NULL) { 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fGlyphToCharMap); 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphToCharMap = NULL; 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fCharToMinGlyphMap != NULL) { 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fCharToMinGlyphMap); 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMinGlyphMap = NULL; 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fCharToMaxGlyphMap != NULL) { 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fCharToMaxGlyphMap); 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fCharToMaxGlyphMap = NULL; 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fGlyphWidths != NULL) { 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fGlyphWidths); 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphWidths = NULL; 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fParaBidi != NULL) { 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_close(fParaBidi); 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fParaBidi = NULL; 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fLineBidi != NULL) { 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_close(fLineBidi); 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineBidi = NULL; 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fStyleRunCount > 0) { 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run; 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleRunLimits); 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleIndices); 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (run = 0; run < fStyleRunCount; run += 1) { 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleRunInfo[run].glyphs); 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleRunInfo[run].positions); 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].glyphs = NULL; 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo[run].positions = NULL; 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fStyleRunInfo); 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunLimits = NULL; 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleIndices = NULL; 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunInfo = NULL; 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStyleRunCount = 0; 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fBreakIterator != NULL) { 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete fBreakIterator; 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fBreakIterator = NULL; 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_bool ParagraphLayout::isComplex(const LEUnicode chars[], le_int32 count) 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode scriptStatus = U_ZERO_ERROR; 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptCode scriptCode = USCRIPT_INVALID_CODE; 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptRun *sr = uscript_openRun(chars, count, &scriptStatus); 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_bool result = FALSE; 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (uscript_nextRun(sr, NULL, NULL, &scriptCode)) { 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isComplex(scriptCode)) { 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = TRUE; 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uscript_closeRun(sr); 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getAscent() const 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0 && fCharCount > 0) { 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout *) this)->computeMetrics(); 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fAscent; 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getDescent() const 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0 && fCharCount > 0) { 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout *) this)->computeMetrics(); 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fDescent; 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getLeading() const 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0 && fCharCount > 0) { 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout *) this)->computeMetrics(); 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fLeading; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 63250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehole_bool ParagraphLayout::isDone() const 63350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 63450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return fLineEnd >= fCharCount; 63550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 63650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::Line *ParagraphLayout::nextLine(float width) 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 63950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (isDone()) { 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineStart = fLineEnd; 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (width > 0) { 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyph = fCharToMinGlyphMap[fLineStart]; 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float widthSoFar = 0; 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (glyph < fGlyphCount && widthSoFar + fGlyphWidths[glyph] <= width) { 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru widthSoFar += fGlyphWidths[glyph++]; 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If no glyphs fit on the line, force one to fit. 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (There shouldn't be any zero width glyphs at the 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // start of a line unless the paragraph consists of 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // only zero width glyphs, because otherwise the zero 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // width glyphs will have been included on the end of 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the previous line...) 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (widthSoFar == 0 && glyph < fGlyphCount) { 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyph += 1; 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineEnd = previousBreak(fGlyphToCharMap[glyph]); 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If this break is at or before the last one, 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find a glyph, starting at the one which didn't 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fit, that produces a break after the last one. 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (fLineEnd <= fLineStart) { 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineEnd = fGlyphToCharMap[glyph++]; 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineEnd = fCharCount; 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return computeVisualRuns(); 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeLevels(UBiDiLevel paragraphLevel) 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode bidiStatus = U_ZERO_ERROR; 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fLevelRuns != NULL) { 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ch; 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run; 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fEmbeddingLevels = LE_NEW_ARRAY(UBiDiLevel, fCharCount); 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (ch = 0, run = 0; run < fLevelRuns->getCount(); run += 1) { 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel runLevel = (UBiDiLevel) fLevelRuns->getValue(run) | UBIDI_LEVEL_OVERRIDE; 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 runLimit = fLevelRuns->getLimit(run); 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (ch < runLimit) { 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fEmbeddingLevels[ch++] = runLevel; 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fParaBidi = ubidi_openSized(fCharCount, 0, &bidiStatus); 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_setPara(fParaBidi, fChars, fCharCount, paragraphLevel, fEmbeddingLevels, &bidiStatus); 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fLevelRuns == NULL) { 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 levelRunCount = ubidi_countRuns(fParaBidi, &bidiStatus); 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ValueRuns *levelRuns = new ValueRuns(levelRunCount); 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 logicalStart = 0; 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run; 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 limit; 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel level; 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (run = 0; run < levelRunCount; run += 1) { 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_getLogicalRun(fParaBidi, logicalStart, &limit, &level); 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru levelRuns->add(level, limit); 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart = limit; 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLevelRuns = levelRuns; 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientLevels = FALSE; 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeScripts() 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode scriptStatus = U_ZERO_ERROR; 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptRun *sr = uscript_openRun(fChars, fCharCount, &scriptStatus); 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ValueRuns *scriptRuns = new ValueRuns(0); 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 limit; 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UScriptCode script; 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (uscript_nextRun(sr, NULL, &limit, &script)) { 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru scriptRuns->add(script, limit); 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uscript_closeRun(sr); 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fScriptRuns = scriptRuns; 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientScripts = FALSE; 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeLocales() 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LocaleRuns *localeRuns = new LocaleRuns(0); 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Locale *defaultLocale = &Locale::getDefault(); 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeRuns->add(defaultLocale, fCharCount); 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLocaleRuns = localeRuns; 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fClientLocales = FALSE; 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status) 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const RunArray *styleRunArrays[] = {fontRuns, fScriptRuns}; 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0]; 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru StyleRuns styleRuns(styleRunArrays, styleCount); 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 styleRunCount = styleRuns.getRuns(NULL, NULL); 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *styleRunLimits = LE_NEW_ARRAY(le_int32, styleRunCount); 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *styleIndices = LE_NEW_ARRAY(le_int32, styleRunCount * styleCount); 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FontRuns *subFontRuns = new FontRuns(0); 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run, offset, *si; 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru styleRuns.getRuns(styleRunLimits, styleIndices); 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru si = styleIndices; 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = 0; 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (run = 0; run < styleRunCount; run += 1) { 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LEFontInstance *runFont = fontRuns->getFont(si[0]); 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 script = fScriptRuns->getValue(si[1]); 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (offset < styleRunLimits[run]) { 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LEFontInstance *subFont = runFont->getSubFont(fChars, &offset, styleRunLimits[run], script, status); 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(status)) { 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete subFontRuns; 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanUp; 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subFontRuns->add(subFont, offset); 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru si += styleCount; 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFontRuns = subFontRuns; 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucleanUp: 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(styleIndices); 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(styleRunLimits); 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::computeMetrics() 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 i, count = fFontRuns->getCount(); 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 maxDL = 0; 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < count; i += 1) { 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LEFontInstance *font = fFontRuns->getFont(i); 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ascent = font->getAscent(); 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 descent = font->getDescent(); 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 leading = font->getLeading(); 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 dl = descent + leading; 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ascent > fAscent) { 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAscent = ascent; 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (descent > fDescent) { 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fDescent = descent; 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (leading > fLeading) { 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLeading = leading; 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dl > maxDL) { 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxDL = dl; 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLeading = maxDL - fDescent; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 1 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct LanguageMap 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *localeCode; 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 languageCode; 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const LanguageMap languageMap[] = 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 837c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"afr", afkLanguageCode}, // Afrikaans 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ara", araLanguageCode}, // Arabic 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"asm", asmLanguageCode}, // Assamese 840c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"bel", belLanguageCode}, // Belarussian 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ben", benLanguageCode}, // Bengali 842c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"bod", tibLanguageCode}, // Tibetan 843c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"bul", bgrLanguageCode}, // Bulgarian 844c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"cat", catLanguageCode}, // Catalan 845c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ces", csyLanguageCode}, // Czech 846c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"che", cheLanguageCode}, // Chechen 847c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"cop", copLanguageCode}, // Coptic 848c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"cym", welLanguageCode}, // Welsh 849c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"dan", danLanguageCode}, // Danish 850c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"deu", deuLanguageCode}, // German 851c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"dzo", dznLanguageCode}, // Dzongkha 852c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ell", ellLanguageCode}, // Greek 853c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"eng", engLanguageCode}, // English 854c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"est", etiLanguageCode}, // Estonian 855c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"eus", euqLanguageCode}, // Basque 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"fas", farLanguageCode}, // Farsi 857c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"fin", finLanguageCode}, // Finnish 858c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"fra", fraLanguageCode}, // French 859c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"gle", gaeLanguageCode}, // Irish Gaelic 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"guj", gujLanguageCode}, // Gujarati 861c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"hau", hauLanguageCode}, // Hausa 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"heb", iwrLanguageCode}, // Hebrew 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"hin", hinLanguageCode}, // Hindi 864c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"hrv", hrvLanguageCode}, // Croatian 865c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"hun", hunLanguageCode}, // Hungarian 866c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"hye", hyeLanguageCode}, // Armenian 867c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ind", indLanguageCode}, // Indonesian 868c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ita", itaLanguageCode}, // Italian 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"jpn", janLanguageCode}, // Japanese 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"kan", kanLanguageCode}, // Kannada 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"kas", kshLanguageCode}, // Kashmiri 872c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"khm", khmLanguageCode}, // Khmer 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"kok", kokLanguageCode}, // Konkani 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"kor", korLanguageCode}, // Korean 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// {"mal_XXX", malLanguageCode}, // Malayalam - Traditional 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"mal", mlrLanguageCode}, // Malayalam - Reformed 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"mar", marLanguageCode}, // Marathi 878c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"mlt", mtsLanguageCode}, // Maltese 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"mni", mniLanguageCode}, // Manipuri 880c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"mon", mngLanguageCode}, // Mongolian 881c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"nep", nepLanguageCode}, // Nepali 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ori", oriLanguageCode}, // Oriya 883c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"pol", plkLanguageCode}, // Polish 884c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"por", ptgLanguageCode}, // Portuguese 885c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"pus", pasLanguageCode}, // Pashto 886c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ron", romLanguageCode}, // Romanian 887c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"rus", rusLanguageCode}, // Russian 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"san", sanLanguageCode}, // Sanskrit 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"sin", snhLanguageCode}, // Sinhalese 890c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"slk", skyLanguageCode}, // Slovak 891c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"snd", sndLanguageCode}, // Sindhi 892c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"slv", slvLanguageCode}, // Slovenian 893c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"spa", espLanguageCode}, // Spanish 894c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"sqi", sqiLanguageCode}, // Albanian 895c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"srp", srbLanguageCode}, // Serbian 896c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"swe", sveLanguageCode}, // Swedish 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"syr", syrLanguageCode}, // Syriac 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"tam", tamLanguageCode}, // Tamil 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"tel", telLanguageCode}, // Telugu 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"tha", thaLanguageCode}, // Thai 901c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"tur", trkLanguageCode}, // Turkish 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"urd", urdLanguageCode}, // Urdu 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"yid", jiiLanguageCode}, // Yiddish 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// {"zhp", zhpLanguageCode}, // Chinese - Phonetic 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho", zhsLanguageCode}, // Chinese 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_CHN", zhsLanguageCode}, // Chinese - China 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_HKG", zhsLanguageCode}, // Chinese - Hong Kong 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_MAC", zhtLanguageCode}, // Chinese - Macao 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_SGP", zhsLanguageCode}, // Chinese - Singapore 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"zho_TWN", zhtLanguageCode} // Chinese - Taiwan 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const le_int32 languageMapCount = ARRAY_SIZE(languageMap); 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getLanguageCode(const Locale *locale) 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char code[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *language = locale->getISO3Language(); 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *country = locale->getISO3Country(); 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(code, language); 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((uprv_strcmp(language, "zho") == 0) && country != NULL) { 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(code, "_"); 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(code, country); 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (le_int32 i = 0; i < languageMapCount; i += 1) { 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(code, languageMap[i].localeCode) == 0) { 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return languageMap[i].languageCode; 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return nullLanguageCode; 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 936b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#else 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// TODO - dummy implementation for right now... 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getLanguageCode(const Locale *locale) 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return nullLanguageCode; 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_bool ParagraphLayout::isComplex(UScriptCode script) 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (script < 0 || script >= (UScriptCode) scriptCodeCount) { 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return complexTable[script]; 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::previousBreak(le_int32 charIndex) 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // skip over any whitespace or control characters, 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // because they can hang in the margin. 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (charIndex < fCharCount && 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (u_isWhitespace(fChars[charIndex]) || 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_iscntrl(fChars[charIndex]))) { 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charIndex += 1; 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create the BreakIterator if we don't already have one 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fBreakIterator == NULL) { 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale thai("th"); 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCharCharacterIterator *iter = new UCharCharacterIterator(fChars, fCharCount); 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fBreakIterator = BreakIterator::createLineInstance(thai, status); 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fBreakIterator->adoptText(iter); 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // return the break location that's at or before 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the character we stopped on. Note: if we're 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // on a break, the "+ 1" will cause preceding to 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // back up to it. 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fBreakIterator->preceding(charIndex + 1); 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::Line *ParagraphLayout::computeVisualRuns() 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode bidiStatus = U_ZERO_ERROR; 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 dirRunCount, visualRun; 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVisualRunLastX = 0; 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVisualRunLastY = 0; 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstVisualRun = getCharRun(fLineStart); 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLastVisualRun = getCharRun(fLineEnd - 1); 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fLineBidi == NULL) { 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLineBidi = ubidi_openSized(fCharCount, 0, &bidiStatus); 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_setLine(fParaBidi, fLineStart, fLineEnd, fLineBidi, &bidiStatus); 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dirRunCount = ubidi_countRuns(fLineBidi, &bidiStatus); 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Line *line = new Line(); 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (visualRun = 0; visualRun < dirRunCount; visualRun += 1) { 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 relStart, run, runLength; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiDirection runDirection = ubidi_getVisualRun(fLineBidi, visualRun, &relStart, &runLength); 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 runStart = fLineStart + relStart; 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 runEnd = runStart + runLength - 1; 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 firstRun = getCharRun(runStart); 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 lastRun = getCharRun(runEnd); 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 startRun = (runDirection == UBIDI_LTR)? firstRun : lastRun; 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 stopRun = (runDirection == UBIDI_LTR)? lastRun + 1 : firstRun - 1; 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 dir = (runDirection == UBIDI_LTR)? 1 : -1; 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (run = startRun; run != stopRun; run += dir) { 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 firstChar = (run == firstRun)? runStart : fStyleRunInfo[run].runBase; 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 lastChar = (run == lastRun)? runEnd : fStyleRunInfo[run].runLimit - 1; 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru appendRun(line, run, firstChar, lastChar); 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return line; 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::appendRun(ParagraphLayout::Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar) 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphBase = fStyleRunInfo[run].glyphBase; 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 inGlyph, outGlyph; 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the glyph indices for all the characters between firstChar and lastChar, 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // make the minimum one be leftGlyph and the maximum one be rightGlyph. 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (need to do this to handle local reorderings like Indic left matras) 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 leftGlyph = fGlyphCount; 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 rightGlyph = -1; 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ch; 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (ch = firstChar; ch <= lastChar; ch += 1) { 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 minGlyph = fCharToMinGlyphMap[ch]; 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 maxGlyph = fCharToMaxGlyphMap[ch]; 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (minGlyph < leftGlyph) { 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leftGlyph = minGlyph; 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (maxGlyph > rightGlyph) { 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightGlyph = maxGlyph; 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fStyleRunInfo[run].level & 1) != 0) { 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 swap = rightGlyph; 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 last = glyphBase + fStyleRunInfo[run].glyphCount - 1; 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Here, we want to remove the glyphBase bias... 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightGlyph = last - leftGlyph; 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leftGlyph = last - swap; 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightGlyph -= glyphBase; 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leftGlyph -= glyphBase; 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set the position bias for the glyphs. If we're at the start of 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // a line, we want the first glyph to be at x = 0, even if it comes 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // from the middle of a layout. If we've got a right-to-left run, we 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // want the left-most glyph to start at the final x position of the 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // previous run, even though this glyph may be in the middle of the 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // run. 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVisualRunLastX -= fStyleRunInfo[run].positions[leftGlyph * 2]; 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Make rightGlyph be the glyph just to the right of 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the run's glyphs 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightGlyph += 1; 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiDirection direction = ((fStyleRunInfo[run].level & 1) == 0)? UBIDI_LTR : UBIDI_RTL; 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount = rightGlyph - leftGlyph; 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEGlyphID *glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount); 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float *positions = LE_NEW_ARRAY(float, glyphCount * 2 + 2); 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 *glyphToCharMap = LE_NEW_ARRAY(le_int32, glyphCount); 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_ARRAY_COPY(glyphs, &fStyleRunInfo[run].glyphs[leftGlyph], glyphCount); 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (outGlyph = 0, inGlyph = leftGlyph * 2; inGlyph <= rightGlyph * 2; inGlyph += 2, outGlyph += 2) { 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru positions[outGlyph] = fStyleRunInfo[run].positions[inGlyph] + fVisualRunLastX; 108150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho positions[outGlyph + 1] = fStyleRunInfo[run].positions[inGlyph + 1] + fVisualRunLastY; 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save the ending position of this run 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to use for the start of the next run 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fVisualRunLastX = positions[outGlyph - 2]; 108750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fVisualRunLastY = positions[outGlyph - 1]; 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((fStyleRunInfo[run].level & 1) == 0) { 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (outGlyph = 0, inGlyph = leftGlyph; inGlyph < rightGlyph; inGlyph += 1, outGlyph += 1) { 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphToCharMap[outGlyph] = fGlyphToCharMap[glyphBase + inGlyph]; 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Because fGlyphToCharMap is stored in logical order to facilitate line breaking, 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we need to map the physical glyph indices to logical indices while we copy the 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // character indices. 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 base = glyphBase + fStyleRunInfo[run].glyphCount - 1; 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (outGlyph = 0, inGlyph = leftGlyph; inGlyph < rightGlyph; inGlyph += 1, outGlyph += 1) { 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphToCharMap[outGlyph] = fGlyphToCharMap[base - inGlyph]; 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru line->append(fStyleRunInfo[run].font, direction, glyphCount, glyphs, positions, glyphToCharMap); 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::getCharRun(le_int32 charIndex) 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (charIndex < 0 || charIndex > fCharCount) { 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 run; 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // NOTE: as long as fStyleRunLimits is well-formed 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the above range check guarantees that we'll never 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fall off the end of the array. 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru run = 0; 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (charIndex >= fStyleRunLimits[run]) { 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru run += 1; 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return run; 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char ParagraphLayout::Line::fgClassID = 0; 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define INITIAL_RUN_CAPACITY 4 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define RUN_CAPACITY_GROW_LIMIT 16 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::Line::~Line() 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 i; 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < fRunCount; i += 1) { 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete fRuns[i]; 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fRuns); 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::Line::getAscent() const 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0) { 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout::Line *)this)->computeMetrics(); 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fAscent; 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::Line::getDescent() const 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0) { 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout::Line *)this)->computeMetrics(); 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fDescent; 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::Line::getLeading() const 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAscent <= 0) { 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((ParagraphLayout::Line *)this)->computeMetrics(); 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fLeading; 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ParagraphLayout::Line::getWidth() const 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const VisualRun *lastRun = getVisualRun(fRunCount - 1); 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lastRun == NULL) { 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount = lastRun->getGlyphCount(); 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const float *positions = lastRun->getPositions(); 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (le_int32) positions[glyphCount * 2]; 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst ParagraphLayout::VisualRun *ParagraphLayout::Line::getVisualRun(le_int32 runIndex) const 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (runIndex < 0 || runIndex >= fRunCount) { 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fRuns[runIndex]; 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::Line::append(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount, 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]) 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fRunCount >= fRunCapacity) { 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fRunCapacity == 0) { 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunCapacity = INITIAL_RUN_CAPACITY; 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRuns = LE_NEW_ARRAY(ParagraphLayout::VisualRun *, fRunCapacity); 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRunCapacity += (fRunCapacity < RUN_CAPACITY_GROW_LIMIT? fRunCapacity : RUN_CAPACITY_GROW_LIMIT); 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRuns = (ParagraphLayout::VisualRun **) LE_GROW_ARRAY(fRuns, fRunCapacity); 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fRuns[fRunCount++] = new ParagraphLayout::VisualRun(font, direction, glyphCount, glyphs, positions, glyphToCharMap); 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ParagraphLayout::Line::computeMetrics() 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 maxDL = 0; 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (le_int32 i = 0; i < fRunCount; i += 1) { 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 ascent = fRuns[i]->getAscent(); 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 descent = fRuns[i]->getDescent(); 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 leading = fRuns[i]->getLeading(); 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 dl = descent + leading; 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ascent > fAscent) { 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAscent = ascent; 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (descent > fDescent) { 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fDescent = descent; 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (leading > fLeading) { 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLeading = leading; 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dl > maxDL) { 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxDL = dl; 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLeading = maxDL - fDescent; 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char ParagraphLayout::VisualRun::fgClassID = 0; 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruParagraphLayout::VisualRun::~VisualRun() 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fGlyphToCharMap); 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fPositions); 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(fGlyphs); 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1252