From 95a189a3be787687113b14d66b607716dd642c8a Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Thu, 15 Jul 2021 12:50:15 +0300 Subject: GmDocument: Right-align RTL decorations --- src/gmdocument.c | 35 ++++++++++++++++++++++++++--------- src/ui/text.c | 4 +--- src/ui/text.h | 1 + 3 files changed, 28 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gmdocument.c b/src/gmdocument.c index 639ddbfb..5034373d 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c @@ -822,16 +822,33 @@ static void doLayout_GmDocument_(iGmDocument *d) { } for (;;) { /* may need to retry */ rts.run.flags |= startOfLine_GmRunFlag; - measure_WrapText(&(iWrapText){ .text = line, - .maxWidth = rts.isWordWrapped - ? d->size.x - run.bounds.pos.x - - rts.indent - rts.rightMargin - : 0 /* unlimited */, - .mode = word_WrapTextMode, - .wrapFunc = typesetOneLine_RunTypesetter_, - .context = &rts }, - rts.run.textParams.font); + iWrapText wrapText = { .text = line, + .maxWidth = rts.isWordWrapped + ? d->size.x - run.bounds.pos.x - + rts.indent - rts.rightMargin + : 0 /* unlimited */, + .mode = word_WrapTextMode, + .wrapFunc = typesetOneLine_RunTypesetter_, + .context = &rts }; + measure_WrapText(&wrapText, rts.run.textParams.font); if (!isLedeParagraph || size_Array(&rts.layout) <= maxLedeLines_) { + if (wrapText.baseDir < 0) { + /* Right-aligned paragraphs need margins and decorations to be flipped. */ + iForEach(Array, pr, &rts.layout) { + iGmRun *prun = pr.value; + const int offset = rts.rightMargin - rts.indent; + prun->bounds.pos.x += offset; + prun->visBounds.pos.x += offset; + } + if (type == bullet_GmLineType || type == link_GmLineType || + type == quote_GmLineType) { + iGmRun *decor = back_Array(&d->layout); + iAssert(decor->flags & decoration_GmRunFlag); + decor->visBounds.pos.x = d->size.x - width_Rect(decor->visBounds) - + decor->visBounds.pos.x + gap_Text * + (type == bullet_GmLineType ? 1.5f : 1); + } + } commit_RunTypesetter_(&rts, d); break; } diff --git a/src/ui/text.c b/src/ui/text.c index 01a9d606..0a3b7b2e 100644 --- a/src/ui/text.c +++ b/src/ui/text.c @@ -1382,9 +1382,6 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { float xCursorMax = 0.0f; const iBool isMonospaced = d->isMonospaced; iAssert(args->text.end >= args->text.start); -// if (args->continueFrom_out) { -// *args->continueFrom_out = args->text.end; -// } /* Split the text into a number of attributed runs that specify exactly which font is used and other attributes such as color. (HarfBuzz shaping is done with one specific font.) */ @@ -1392,6 +1389,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { init_AttributedText(&attrText, args->text, args->maxLen, d, get_Color(args->color), args->baseDir); if (args->wrap) { + args->wrap->baseDir = attrText.isBaseRTL ? -1 : +1; /* TODO: Duplicated args? */ iAssert(equalRange_Rangecc(args->wrap->text, args->text)); /* Initialize the wrap range. */ diff --git a/src/ui/text.h b/src/ui/text.h index d3a9f844..41e7671e 100644 --- a/src/ui/text.h +++ b/src/ui/text.h @@ -207,6 +207,7 @@ struct Impl_WrapText { enum iWrapTextMode mode; iBool (*wrapFunc)(iWrapText *, iRangecc wrappedText, int origin, int advance, iBool isBaseRTL); void * context; + int baseDir; /* set to +1 for LTR, -1 for RTL /* internal */ iRangecc wrapRange_; }; -- cgit v1.2.3