1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h" 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ubidi.h" 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h" 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LETypes.h" 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/loengine.h" 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/playout.h" 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/plruns.h" 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "pflow.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "arraymem.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucreader.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Move the line below out of this comment 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to add a locale run to the pl_paragraphs 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * that are created. 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST_LOCALE "zh_TW" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MARGIN 10 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define LINE_GROW 32 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define PARA_GROW 8 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CH_LF 0x000A 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CH_CR 0x000D 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CH_LSEP 0x2028 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CH_PSEP 0x2029 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct pf_object 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_paragraph **fParagraphLayout; 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fParagraphCount; 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fParagraphMax; 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fParagraphGrow; 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fLineCount; 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fLinesMax; 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fLinesGrow; 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_line **fLines; 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *fChars; 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fLineHeight; 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fAscent; 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fWidth; 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 fHeight; 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBiDiLevel fParagraphLevel; 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct pf_object pf_object; 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic LEUnicode *skipLineEnd(LEUnicode *ptr) 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ptr[0] == CH_CR && ptr[1] == CH_LF) { 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ptr += 1; 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ptr + 1; 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic le_int32 findFontRun(const pl_fontRuns *fontRuns, le_int32 offset) 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 runCount = pl_getFontRunCount(fontRuns); 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 run; 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (run = 0; run < runCount; run += 1) { 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pl_getFontRunLimit(fontRuns, run) > offset) { 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return run; 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void subsetFontRuns(const pl_fontRuns *fontRuns, le_int32 start, le_int32 limit, pl_fontRuns *sub) 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 startRun = findFontRun(fontRuns, start); 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 endRun = findFontRun(fontRuns, limit - 1); 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 run; 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_resetFontRuns(sub); 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (run = startRun; run <= endRun; run += 1) { 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const le_font *runFont = pl_getFontRunFont(fontRuns, run); 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 runLimit = pl_getFontRunLimit(fontRuns, run) - start; 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (run == endRun) { 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLimit = limit - start; 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_addFontRun(sub, runFont, runLimit); 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupf_flow *pf_create(const LEUnicode chars[], le_int32 charCount, const pl_fontRuns *fontRuns, LEErrorCode *status) 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_object *flow; 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 ascent = 0; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 descent = 0; 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 leading = 0; 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_localeRuns *locales = NULL; 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_fontRuns *fr; 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *pStart; 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static const LEUnicode separators[] = {CH_LF, CH_CR, CH_LSEP, CH_PSEP, 0x0000}; 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(*status)) { 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow = NEW_ARRAY(pf_object, 1); 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphLayout = NULL; 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphCount = 0; 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphMax = PARA_GROW; 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphGrow = PARA_GROW; 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fLineCount = 0; 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fLinesMax = LINE_GROW; 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fLinesGrow = LINE_GROW; 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fLines = NULL; 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fChars = NULL; 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fLineHeight = -1; 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fAscent = -1; 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fWidth = -1; 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fHeight = -1; 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphLevel = UBIDI_DEFAULT_LTR; 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fr = pl_openEmptyFontRuns(0); 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef TEST_LOCALE 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru locales = pl_openEmptyLocaleRuns(0); 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fLines = NEW_ARRAY(pl_line *, flow->fLinesMax); 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphLayout = NEW_ARRAY(pl_paragraph *, flow->fParagraphMax); 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fChars = NEW_ARRAY(LEUnicode, charCount + 1); 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_ARRAY_COPY(flow->fChars, chars, charCount); 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fChars[charCount] = 0; 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pStart = &flow->fChars[0]; 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (*pStart != 0) { 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *pEnd = u_strpbrk(pStart, separators); 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 pAscent, pDescent, pLeading; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_paragraph *paragraphLayout = NULL; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pEnd == NULL) { 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pEnd = &flow->fChars[charCount]; 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pEnd != pStart) { 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru subsetFontRuns(fontRuns, pStart - flow->fChars, pEnd - flow->fChars, fr); 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef TEST_LOCALE 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_resetLocaleRuns(locales); 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_addLocaleRun(locales, TEST_LOCALE, pEnd - pStart); 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru paragraphLayout = pl_create(pStart, pEnd - pStart, fr, NULL, NULL, locales, flow->fParagraphLevel, FALSE, status); 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(*status)) { 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; /* return? something else? */ 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (flow->fParagraphLevel == UBIDI_DEFAULT_LTR) { 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphLevel = pl_getParagraphLevel(paragraphLayout); 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pAscent = pl_getAscent(paragraphLayout); 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pDescent = pl_getDescent(paragraphLayout); 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pLeading = pl_getLeading(paragraphLayout); 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pAscent > ascent) { 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ascent = pAscent; 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pDescent > descent) { 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru descent = pDescent; 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pLeading > leading) { 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru leading = pLeading; 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (flow->fParagraphCount >= flow->fParagraphMax) { 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphLayout = (pl_paragraph **) GROW_ARRAY(flow->fParagraphLayout, flow->fParagraphMax + flow->fParagraphGrow); 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphMax += flow->fParagraphGrow; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fParagraphLayout[flow->fParagraphCount++] = paragraphLayout; 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*pEnd == 0) { 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pStart = skipLineEnd(pEnd); 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fLineHeight = ascent + descent + leading; 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flow->fAscent = ascent; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_closeLocaleRuns(locales); 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_closeFontRuns(fr); 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (pf_flow *) flow; 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid pf_close(pf_flow *flow) 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_object *obj = (pf_object *) flow; 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 i; 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (i = 0; i < obj->fLineCount; i += 1) { 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(obj->fLines[i]); 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(obj->fLines); 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (i = 0; i < obj->fParagraphCount; i += 1) { 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_close(obj->fParagraphLayout[i]); 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(obj->fParagraphLayout); 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(obj->fChars); 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(obj); 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 pf_getAscent(pf_flow *flow) 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_object *obj = (pf_object *) flow; 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return obj->fAscent; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 pf_getLineHeight(pf_flow *flow) 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_object *obj = (pf_object *) flow; 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return obj->fLineHeight; 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 pf_getLineCount(pf_flow *flow) 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_object *obj = (pf_object *) flow; 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return obj->fLineCount; 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void addLine(pf_object *obj, pl_line *line) 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (obj->fLineCount >= obj->fLinesMax) { 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru obj->fLines = (pl_line **) GROW_ARRAY(obj->fLines, obj->fLinesMax + obj->fLinesGrow); 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru obj->fLinesMax += obj->fLinesGrow; 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru obj->fLines[obj->fLineCount++] = line; 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid pf_breakLines(pf_flow *flow, le_int32 width, le_int32 height) 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_object *obj = (pf_object *) flow; 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 li, p; 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float lineWidth; 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_line *line; 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru obj->fHeight = height; 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* don't re-break if the width hasn't changed */ 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (obj->fWidth == width) { 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru obj->fWidth = width; 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lineWidth = (float) (width - 2 * MARGIN); 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Free the old Lines... */ 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (li = 0; li < obj->fLineCount; li += 1) { 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_closeLine(obj->fLines[li]); 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru obj->fLineCount = 0; 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (p = 0; p < obj->fParagraphCount; p += 1) { 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_paragraph *paragraphLayout = obj->fParagraphLayout[p]; 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (paragraphLayout != NULL) { 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_reflow(paragraphLayout); 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((line = pl_nextLine(paragraphLayout, lineWidth)) != NULL) { 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru addLine(obj, line); 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru addLine(obj, NULL); 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid pf_draw(pf_flow *flow, rs_surface *surface, le_int32 firstLine, le_int32 lastLine) 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_object *obj = (pf_object *) flow; 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 li, x, y; 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru x = MARGIN; 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru y = obj->fAscent; 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (li = firstLine; li <= lastLine; li += 1) { 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const pl_line *line = obj->fLines[li]; 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (line != NULL) { 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 runCount = pl_countLineRuns(line); 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 run; 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (obj->fParagraphLevel == UBIDI_RTL) { 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 lastX = pl_getLineWidth(line); 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru x = (obj->fWidth - lastX - MARGIN); 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (run = 0; run < runCount; run += 1) { 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const pl_visualRun *visualRun = pl_getLineVisualRun(line, run); 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 glyphCount = pl_getVisualRunGlyphCount(visualRun); 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const le_font *font = pl_getVisualRunFont(visualRun); 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const LEGlyphID *glyphs = pl_getVisualRunGlyphs(visualRun); 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const float *positions = pl_getVisualRunPositions(visualRun); 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rs_drawGlyphs(surface, font, glyphs, glyphCount, positions, x, y, obj->fWidth, obj->fHeight); 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru y += obj->fLineHeight; 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupf_flow *pf_factory(const char *fileName, const le_font *font, gs_guiSupport *guiSupport) 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEErrorCode status = LE_NO_ERROR; 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 charCount; 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *text = uc_readFile(fileName, guiSupport, &charCount); 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_fontRuns *fontRuns; 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_flow *result = NULL; 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (text == NULL) { 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fontRuns = pl_openEmptyFontRuns(0); 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_addFontRun(fontRuns, font, charCount); 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = pf_create(text, charCount, fontRuns, &status); 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pf_close(result); 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = NULL; 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pl_closeFontRuns(fontRuns); 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DELETE_ARRAY(text); 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 382