1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************************* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert * Copyright (C) 2016 and later: Unicode, Inc. and others. 564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert * License & terms of use: http://www.unicode.org/copyright.html#License 664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert * 764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert ******************************************************************************* 864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert ******************************************************************************* 964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert * 10c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Copyright (C) 1999-2015, International Business Machines 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Corporation and others. All Rights Reserved. 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************************* 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * file name: Paragraph.cpp 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * created on: 09/06/2000 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * created by: Eric R. Mader 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ubidi.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h" 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/ParagraphLayout.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "RenderingSurface.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "paragraph.h" 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "UnicodeReader.h" 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MARGIN 10 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define LINE_GROW 32 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define PARA_GROW 8 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CH_LF 0x000A 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CH_CR 0x000D 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CH_LSEP 0x2028 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CH_PSEP 0x2029 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic LEUnicode *skipLineEnd(LEUnicode *ptr) 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ptr[0] == CH_CR && ptr[1] == CH_LF) { 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ptr += 1; 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ptr + 1; 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic le_int32 findRun(const RunArray *runArray, le_int32 offset) 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 runCount = runArray->getCount(); 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (le_int32 run = 0; run < runCount; run += 1) { 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (runArray->getLimit(run) > offset) { 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return run; 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void subsetFontRuns(const FontRuns *fontRuns, le_int32 start, le_int32 limit, FontRuns *sub) 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 startRun = findRun(fontRuns, start); 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 endRun = findRun(fontRuns, limit - 1); 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sub->reset(); 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (le_int32 run = startRun; run <= endRun; run += 1) { 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const LEFontInstance *runFont = fontRuns->getFont(run); 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 runLimit = fontRuns->getLimit(run) - start; 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (run == endRun) { 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLimit = limit - start; 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sub->add(runFont, runLimit); 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruParagraph::Paragraph(const LEUnicode chars[], int32_t charCount, const FontRuns *fontRuns, LEErrorCode &status) 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : fParagraphLayout(NULL), fParagraphCount(0), fParagraphMax(PARA_GROW), fParagraphGrow(PARA_GROW), 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLineCount(0), fLinesMax(LINE_GROW), fLinesGrow(LINE_GROW), fLines(NULL), fChars(NULL), 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLineHeight(-1), fAscent(-1), fWidth(-1), fHeight(-1), fParagraphLevel(UBIDI_DEFAULT_LTR) 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static const LEUnicode separators[] = {CH_LF, CH_CR, CH_LSEP, CH_PSEP, 0x0000}; 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 ascent = 0; 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 descent = 0; 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 leading = 0; 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocaleRuns *locales = NULL; 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FontRuns fr(0); 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLines = LE_NEW_ARRAY(const ParagraphLayout::Line *, fLinesMax); 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fParagraphLayout = LE_NEW_ARRAY(ParagraphLayout *, fParagraphMax); 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fChars = LE_NEW_ARRAY(LEUnicode, charCount + 1); 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_ARRAY_COPY(fChars, chars, charCount); 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fChars[charCount] = 0; 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *pStart = &fChars[0]; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (*pStart != 0) { 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *pEnd = u_strpbrk(pStart, separators); 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 pAscent, pDescent, pLeading; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParagraphLayout *paragraphLayout = NULL; 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pEnd == NULL) { 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pEnd = &fChars[charCount]; 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pEnd != pStart) { 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru subsetFontRuns(fontRuns, pStart - fChars, pEnd - fChars, &fr); 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru paragraphLayout = new ParagraphLayout(pStart, pEnd - pStart, &fr, NULL, NULL, locales, fParagraphLevel, FALSE, status); 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 124c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete paragraphLayout; 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; // return? something else? 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fParagraphLevel == UBIDI_DEFAULT_LTR) { 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fParagraphLevel = paragraphLayout->getParagraphLevel(); 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pAscent = paragraphLayout->getAscent(); 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pDescent = paragraphLayout->getDescent(); 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pLeading = paragraphLayout->getLeading(); 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pAscent > ascent) { 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ascent = pAscent; 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pDescent > descent) { 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru descent = pDescent; 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pLeading > leading) { 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru leading = pLeading; 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fParagraphCount >= fParagraphMax) { 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fParagraphLayout = (ParagraphLayout **) LE_GROW_ARRAY(fParagraphLayout, fParagraphMax + fParagraphGrow); 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fParagraphMax += fParagraphGrow; 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fParagraphLayout[fParagraphCount++] = paragraphLayout; 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*pEnd == 0) { 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pStart = skipLineEnd(pEnd); 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLineHeight = ascent + descent + leading; 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fAscent = ascent; 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruParagraph::~Paragraph() 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (le_int32 line = 0; line < fLineCount; line += 1) { 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete /*(LineInfo *)*/ fLines[line]; 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 173c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert for (le_int32 paragraph = 0; paragraph < fParagraphCount; paragraph += 1) { 174c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete fParagraphLayout[paragraph]; 175c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 176c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(fLines); 178c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LE_DELETE_ARRAY(fParagraphLayout); 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(fChars); 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid Paragraph::addLine(const ParagraphLayout::Line *line) 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fLineCount >= fLinesMax) { 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLines = (const ParagraphLayout::Line **) LE_GROW_ARRAY(fLines, fLinesMax + fLinesGrow); 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLinesMax += fLinesGrow; 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLines[fLineCount++] = line; 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid Paragraph::breakLines(le_int32 width, le_int32 height) 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fHeight = height; 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // don't re-break if the width hasn't changed 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fWidth == width) { 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fWidth = width; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float lineWidth = (float) (width - 2 * MARGIN); 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ParagraphLayout::Line *line; 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Free the old LineInfo's... 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (le_int32 li = 0; li < fLineCount; li += 1) { 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete fLines[li]; 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLineCount = 0; 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (le_int32 p = 0; p < fParagraphCount; p += 1) { 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParagraphLayout *paragraphLayout = fParagraphLayout[p]; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (paragraphLayout != NULL) { 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru paragraphLayout->reflow(); 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((line = paragraphLayout->nextLine(lineWidth)) != NULL) { 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru addLine(line); 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru addLine(NULL); 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid Paragraph::draw(RenderingSurface *surface, le_int32 firstLine, le_int32 lastLine) 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 li, x, y; 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru x = MARGIN; 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru y = fAscent; 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (li = firstLine; li <= lastLine; li += 1) { 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ParagraphLayout::Line *line = fLines[li]; 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (line != NULL) { 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 runCount = line->countRuns(); 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 run; 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fParagraphLevel == UBIDI_RTL) { 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 lastX = line->getWidth(); 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru x = (fWidth - lastX - MARGIN); 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (run = 0; run < runCount; run += 1) { 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ParagraphLayout::VisualRun *visualRun = line->getVisualRun(run); 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 glyphCount = visualRun->getGlyphCount(); 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const LEFontInstance *font = visualRun->getFont(); 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const LEGlyphID *glyphs = visualRun->getGlyphs(); 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const float *positions = visualRun->getPositions(); 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru surface->drawGlyphs(font, glyphs, glyphCount, positions, x, y, fWidth, fHeight); 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru y += fLineHeight; 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruParagraph *Paragraph::paragraphFactory(const char *fileName, const LEFontInstance *font, GUISupport *guiSupport) 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEErrorCode status = LE_NO_ERROR; 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 charCount; 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *text = UnicodeReader::readFile(fileName, guiSupport, charCount); 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Paragraph *result = NULL; 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (text == NULL) { 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FontRuns fontRuns(0); 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fontRuns.add(font, charCount); 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = new Paragraph(text, charCount, &fontRuns, status); 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete result; 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = NULL; 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(text); 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 290