=> 2f3987f5e54d95658f95c6991b0644bc15eedabf
[1mdiff --git a/res/arabic.fontpack/fontpack.ini b/res/arabic.fontpack/fontpack.ini[m [1mindex 305878ce..48b40d82 100644[m [1m--- a/res/arabic.fontpack/fontpack.ini[m [1m+++ b/res/arabic.fontpack/fontpack.ini[m [36m@@ -3,4 +3,5 @@[m [mversion = 1[m [arabic][m name = "Noto Sans Arabic UI"[m auxiliary = true[m [32m+[m[32mallowspace = true # usually auxiliary fonts are not used for spaces[m regular = "NotoSansArabicUI-Regular.ttf"[m [1mdiff --git a/src/fontpack.c b/src/fontpack.c[m [1mindex 9baedc0e..b135ea43 100644[m [1m--- a/src/fontpack.c[m [1m+++ b/src/fontpack.c[m [36m@@ -350,8 +350,8 @@[m [mvoid handleIniKeyValue_FontPack_(void *context, const iString *table, const iStr[m else if (!cmp_String(key, "auxiliary") && value->type == boolean_TomlType) {[m iChangeFlags(d->loadSpec->flags, auxiliary_FontSpecFlag, value->value.boolean);[m }[m [31m- else if (!cmp_String(key, "arabic") && value->type == boolean_TomlType) {[m [31m- iChangeFlags(d->loadSpec->flags, arabic_FontSpecFlag, value->value.boolean);[m [32m+[m[32m else if (!cmp_String(key, "allowspace") && value->type == boolean_TomlType) {[m [32m+[m[32m iChangeFlags(d->loadSpec->flags, allowSpacePunct_FontSpecFlag, value->value.boolean);[m }[m else if (!cmp_String(key, "tweaks")) {[m iChangeFlags(d->loadSpec->flags, fixNunitoKerning_FontSpecFlag,[m [1mdiff --git a/src/fontpack.h b/src/fontpack.h[m [1mindex 429afb5d..f69e2adc 100644[m [1m--- a/src/fontpack.h[m [1m+++ b/src/fontpack.h[m [36m@@ -110,10 +110,10 @@[m [miDeclareType(FontSpec)[m iDeclareTypeConstruction(FontSpec)[m [m enum iFontSpecFlags {[m [31m- override_FontSpecFlag = iBit(1),[m [31m- monospace_FontSpecFlag = iBit(2), /* can be used in preformatted content */[m [31m- auxiliary_FontSpecFlag = iBit(3), /* only used for looking up glyphs missing from other fonts */[m [31m- arabic_FontSpecFlag = iBit(4),[m [32m+[m[32m override_FontSpecFlag = iBit(1),[m [32m+[m[32m monospace_FontSpecFlag = iBit(2), /* can be used in preformatted content */[m [32m+[m[32m auxiliary_FontSpecFlag = iBit(3), /* only used for looking up glyphs missing from other fonts */[m [32m+[m[32m allowSpacePunct_FontSpecFlag = iBit(4), /* space/punctuation glyphs from this auxiliary font can be used */[m fixNunitoKerning_FontSpecFlag = iBit(31), /* manual hardcoded kerning tweaks for Nunito */[m };[m [m [1mdiff --git a/src/gmdocument.c b/src/gmdocument.c[m [1mindex e37d585e..0adf5243 100644[m [1m--- a/src/gmdocument.c[m [1m+++ b/src/gmdocument.c[m [36m@@ -493,10 +493,15 @@[m [mstatic iBool typesetOneLine_RunTypesetter_(iWrapText *wrap, iRangecc wrapRange,[m int origin, int advance) {[m iAssert(wrapRange.start <= wrapRange.end);[m trimEnd_Rangecc(&wrapRange);[m [31m-// printf("typeset: {%s}\n", cstr_Rangecc(wrapRange));[m iRunTypesetter *d = wrap->context;[m d->run.text = wrapRange;[m applyAttributes_RunTypesetter_(d, attrib);[m [32m+[m[32m#if 0[m [32m+[m[32m const int msr = measureRange_Text(d->run.font, wrapRange).advance.x;[m [32m+[m[32m if (iAbs(msr - advance) > 3) {[m [32m+[m[32m printf("\n[RunTypesetter] wrong wrapRange advance! actual:%d wrapped:%d\n\n", msr, advance);[m [32m+[m[32m }[m [32m+[m[32m#endif[m if (~d->run.flags & startOfLine_GmRunFlag && d->lineHeightReduction > 0.0f) {[m d->pos.y -= d->lineHeightReduction * lineHeight_Text(d->baseFont);[m }[m [36m@@ -508,7 +513,7 @@[m [mstatic iBool typesetOneLine_RunTypesetter_(iWrapText *wrap, iRangecc wrapRange,[m d->run.visBounds = d->run.bounds;[m d->run.visBounds.size.x = dims.x;[m d->run.isRTL = attrib.isBaseRTL;[m [31m- printf("origin:%d isRTL:%d\n{%s}\n", origin, attrib.isBaseRTL, cstr_Rangecc(wrapRange));[m [32m+[m[32m// printf("origin:%d isRTL:%d\n{%s}\n", origin, attrib.isBaseRTL, cstr_Rangecc(wrapRange));[m pushBack_Array(&d->layout, &d->run);[m d->run.flags &= ~startOfLine_GmRunFlag;[m d->pos.y += lineHeight_Text(d->baseFont) * prefs_App()->lineSpacing;[m [1mdiff --git a/src/gmdocument.h b/src/gmdocument.h[m [1mindex 4a248550..94a494e8 100644[m [1m--- a/src/gmdocument.h[m [1m+++ b/src/gmdocument.h[m [36m@@ -139,10 +139,10 @@[m [mstruct Impl_GmRun {[m uint32_t isRTL : 1;[m uint32_t color : 7; /* see max_ColorId */[m [m [31m- uint32_t font : 10;[m [32m+[m[32m uint32_t font : 13;[m uint32_t mediaType : 3; /* note: max_MediaType means preformatted block */[m [32m+[m[32m uint32_t mediaId : 12; /* zero if not an image */[m uint32_t lineType : 3;[m [31m- uint32_t mediaId : 15; /* zero if not an image */[m uint32_t isLede : 1;[m };[m };[m [1mdiff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c[m [1mindex 8fefb95c..924dc0c4 100644[m [1m--- a/src/ui/documentwidget.c[m [1m+++ b/src/ui/documentwidget.c[m [36m@@ -4522,8 +4522,10 @@[m [mstatic void drawRun_DrawContext_(void *context, const iGmRun *run) {[m }[m }[m }[m [31m-// drawRect_Paint(&d->paint, (iRect){ visPos, run->bounds.size }, green_ColorId);[m [31m-// drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, red_ColorId);[m [32m+[m[32m if (0) {[m [32m+[m[32m drawRect_Paint(&d->paint, (iRect){ visPos, run->bounds.size }, green_ColorId);[m [32m+[m[32m drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, red_ColorId);[m [32m+[m[32m }[m }[m [m static int drawSideRect_(iPaint *p, iRect rect) {[m [1mdiff --git a/src/ui/text.c b/src/ui/text.c[m [1mindex 7afaf583..d22faea1 100644[m [1m--- a/src/ui/text.c[m [1m+++ b/src/ui/text.c[m [36m@@ -214,7 +214,6 @@[m [mstatic void init_Font(iFont *d, const iFontSpec *fontSpec, const iFontFile *font[m d->baseline = fontFile->ascent * d->yScale;[m d->vertOffset = d->height * (1.0f - glyphScale) / 2 * fontSpec->vertOffsetScale[scaleType];[m d->table = NULL;[m [31m- // printf("{%s} height:%d baseline:%d\n", cstr_String(&d->fontSpec->id), d->height, d->baseline);[m }[m [m static void deinit_Font(iFont *d) {[m [36m@@ -934,6 +933,12 @@[m [mstatic void finishRun_AttributedText_(iAttributedText *d, iAttributedRun *run, i[m iAssert(endAt >= 0 && endAt <= size_Array(&d->logical));[m finishedRun.logical.end = endAt;[m if (!isEmpty_Range(&finishedRun.logical)) {[m [32m+[m[32m#if 0[m [32m+[m[32m /* Colorize individual runs to see boundaries. */[m [32m+[m[32m static int dbg;[m [32m+[m[32m static const int dbgClr[3] = { red_ColorId, green_ColorId, blue_ColorId };[m [32m+[m[32m finishedRun.attrib.colorId = dbgClr[dbg++ % 3];[m [32m+[m[32m#endif[m pushBack_Array(&d->runs, &finishedRun);[m run->flags.isLineBreak = iFalse;[m run->flags.isArabic = iFalse;[m [36m@@ -1120,15 +1125,18 @@[m [mstatic void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir, iCh[m continue;[m }[m if (ch == 0x20) {[m [31m- if (run.font->fontSpec->flags & auxiliary_FontSpecFlag) {[m [32m+[m[32m if (run.font->fontSpec->flags & auxiliary_FontSpecFlag &&[m [32m+[m[32m ~run.font->fontSpec->flags & allowSpacePunct_FontSpecFlag) {[m finishRun_AttributedText_(d, &run, pos);[m [31m- run.font = d->font; /* never use space from the symbols font, it's too wide */[m [32m+[m[32m run.font = d->font; /* auxilitary font space not allowed, could be wrong width */[m }[m continue;[m }[m iFont *currentFont = attribFont;[m [31m- if (run.font->fontSpec->flags & arabic_FontSpecFlag && isPunct_Char(ch)) {[m [31m- currentFont = run.font; /* remain as Arabic for whitespace */[m [32m+[m[32m if (run.font->fontSpec->flags & auxiliary_FontSpecFlag &&[m [32m+[m[32m run.font->fontSpec->flags & allowSpacePunct_FontSpecFlag &&[m [32m+[m[32m isPunct_Char(ch)) {[m [32m+[m[32m currentFont = run.font; /* keep the current font */[m }[m const iGlyph *glyph = glyph_Font_(currentFont, ch);[m if (index_Glyph_(glyph) && glyph->font != run.font) {[m [36m@@ -1153,8 +1161,10 @@[m [mstatic void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir, iCh[m printf("[AttributedText] %zu runs:\n", size_Array(&d->runs));[m iConstForEach(Array, i, &d->runs) {[m const iAttributedRun *run = i.value;[m [31m- printf(" %zu %s log:%d...%d vis:%d...%d {%s}\n", index_ArrayConstIterator(&i),[m [32m+[m[32m printf(" %zu %s fnt:%d log:%d...%d vis:%d...%d {%s}\n",[m [32m+[m[32m index_ArrayConstIterator(&i),[m run->attrib.isRTL ? "<-" : "->",[m [32m+[m[32m fontId_Text_(run->font),[m run->logical.start, run->logical.end - 1,[m logToVis[run->logical.start], logToVis[run->logical.end - 1],[m cstr_Rangecc(sourceRange_AttributedText_(d, run->logical)));[m [36m@@ -1598,6 +1608,7 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m wrap->hitPoint.y < orig.y + yCursor + d->height);[m iBool wasCharHit = iFalse; /* on this line */[m float breakAdvance = -1.0f;[m [32m+[m[32m size_t breakRunIndex = iInvalidPos;[m iAssert(wrapPosRange.end == textLen);[m /* Determine ends of wrapRuns and wrapVisRange. */[m int safeBreakPos = -1;[m [36m@@ -1621,7 +1632,8 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m iAssert(run->font == buf->font);[m shape_GlyphBuffer_(buf);[m iChar prevCh = 0;[m [31m- lastAttrib = run->attrib; [m [32m+[m[32m lastAttrib = run->attrib;[m [32m+[m[32m// printf("checking run %zu...\n", runIndex);[m for (unsigned int ir = 0; ir < buf->glyphCount; ir++) {[m const int i = (run->attrib.isRTL ? buf->glyphCount - ir - 1 : ir);[m const hb_glyph_info_t *info = &buf->glyphInfo[i];[m [36m@@ -1648,24 +1660,27 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m iAssert(xAdvance >= 0);[m if (args->wrap->mode == word_WrapTextMode) {[m /* When word wrapping, only consider certain places breakable. */[m [31m- if (!isPunct_Char(ch) && (prevCh == '-' || prevCh == '/')) {[m [32m+[m[32m if ((prevCh == '-' || prevCh == '/') && !isPunct_Char(ch)) {[m safeBreakPos = logPos;[m breakAdvance = wrapAdvance;[m [31m-// printf("breakAdv_A:%f\n", breakAdvance);[m [32m+[m[32m breakRunIndex = runIndex;[m [32m+[m[32m// printf("sbp:%d breakAdv_A:%f\n", safeBreakPos, breakAdvance);[m // isSoftHyphenBreak = iFalse;[m }[m else if (isSpace_Char(ch)) {[m safeBreakPos = logPos;[m breakAdvance = wrapAdvance;[m [31m-// printf("breakAdv_B:%f sbb:%d\n", breakAdvance, safeBreakPos);[m [32m+[m[32m breakRunIndex = runIndex;[m [32m+[m[32m// printf("sbp:%d breakAdv_B:%f\n", safeBreakPos, breakAdvance);[m // isSoftHyphenBreak = iFalse;[m }[m prevCh = ch;[m }[m else {[m [31m- safeBreakPos = logPos;[m [31m- breakAdvance = wrapAdvance;[m [31m- wrapAttrib = run->attrib;[m [32m+[m[32m safeBreakPos = logPos;[m [32m+[m[32m breakAdvance = wrapAdvance;[m [32m+[m[32m breakRunIndex = runIndex;[m [32m+[m[32m wrapAttrib = run->attrib;[m }[m if (isHitPointOnThisLine) {[m if (wrap->hitPoint.x >= orig.x + wrapAdvance &&[m [36m@@ -1681,7 +1696,9 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m if (wrap->maxWidth > 0 &&[m wrapAdvance + xOffset + glyph->d[0].x + glyph->rect[0].size.x >[m args->wrap->maxWidth) {[m [31m-// printf("safeBreakPos:%d\n", safeBreakPos);[m [32m+[m[32m// printf("out of room at lp:%d! safeBreakPos:%d (idx:%zu) breakAdv:%f\n",[m [32m+[m[32m// logPos, safeBreakPos,[m [32m+[m[32m// breakRunIndex, breakAdvance);[m if (safeBreakPos >= 0) {[m wrapPosRange.end = safeBreakPos;[m }[m [36m@@ -1697,6 +1714,7 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m }[m wrapPosRange.end = logPos;[m breakAdvance = wrapAdvance;[m [32m+[m[32m breakRunIndex = runIndex;[m }[m wrapResumePos = wrapPosRange.end;[m if (args->wrap->mode != anyCharacter_WrapTextMode) {[m [36m@@ -1704,14 +1722,14 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m wrapResumePos++; /* skip space */[m }[m }[m [31m- wrapRuns.end = runIndex + 1; /* still includes this run */[m [31m- wrapResumeRunIndex = runIndex; /* ...but continue from the same one */[m [32m+[m[32m wrapRuns.end = breakRunIndex + 1; /* still includes this run */[m [32m+[m[32m wrapResumeRunIndex = breakRunIndex; /* ...but continue from the same one */[m [32m+[m[32m// printf("-> wrapAdv:%f (breakAdv:%f)\n", wrapAdvance, breakAdvance);[m wrapAdvance = breakAdvance;[m [31m-// printf("-> wrapAdv:%f (breakAdv)\n", wrapAdvance);[m [32m+[m[32m// printf("wrapResumePos:%d\n", wrapResumePos);[m break;[m }[m wrapAdvance += xAdvance;[m [31m- printf("lp:%d wrap:%f\n", logPos, wrapAdvance);[m /* Additional kerning tweak. It would be better to use HarfBuzz font callbacks,[m but they don't seem to get called? */[m if (i + 1 < buf->glyphCount) {[m [36m@@ -1720,6 +1738,7 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m buf->glyphInfo[i + 1].codepoint);[m }[m }[m [32m+[m[32m// printf("...finished checking run %zu\n", runIndex);[m }[m if (isHitPointOnThisLine && wrap->hitPoint.x >= orig.x + wrapAdvance) {[m /* On the right side. */[m [36m@@ -1774,16 +1793,17 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m }[m }[m }[m [31m- }[m #if 0[m [31m- printf("Run order: ");[m [31m- iConstForEach(Array, ro, &runOrder) {[m [31m- const size_t *idx = ro.value;[m [31m- printf("%zu {%s}\n", *idx,[m [31m- cstr_Rangecc(sourceRange_AttributedText_(&attrText, ((const iAttributedRun *) at_Array(&attrText.runs, *idx))->logical)));[m [31m- }[m [31m- printf("\n");[m [32m+[m[32m printf("Run order: ");[m [32m+[m[32m iConstForEach(Array, ro, &runOrder) {[m [32m+[m[32m const size_t *idx = ro.value;[m [32m+[m[32m printf("%zu {%s}\n", *idx,[m [32m+[m[32m cstr_Rangecc(sourceRange_AttributedText_(&attrText, ((const iAttributedRun *) at_Array(&attrText.runs, *idx))->logical)));[m [32m+[m[32m }[m [32m+[m[32m printf("\n");[m #endif[m [32m+[m[41m [m [32m+[m[32m }[m iAssert(size_Array(&runOrder) == size_Range(&wrapRuns));[m /* Alignment. */[m int origin = 0;[m [36m@@ -1791,12 +1811,7 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m if (isRightAligned) {[m if (layoutBound > 0) {[m origin = layoutBound - wrapAdvance;[m [31m- printf("orig:%d (lbo:%d wrapAdv:%f)\n", origin, layoutBound, wrapAdvance);[m }[m [31m- printf("yes; base RTL\n");[m [31m- }[m [31m- else {[m [31m- printf("not base RTL\n");[m }[m /* Make a callback for each wrapped line. */[m if (wrap && wrap->wrapFunc &&[m [36m@@ -1866,8 +1881,6 @@[m [mstatic iRect run_Font_(iFont *d, const iRunArgs *args) {[m const int bl1 = attrText.baseFont->baseline + attrText.baseFont->vertOffset;[m const int bl2 = run->font->baseline + run->font->vertOffset;[m dst.y += bl1 - bl2;[m [31m-// printf("baseline difference: run %d, base %d\n",[m [31m-// run->font->baseline, attrText.baseFont->baseline);[m }[m if (mode & visualFlag_RunMode) {[m if (isEmpty_Rect(bounds)) {[m
text/gemini; charset=utf-8
This content has been proxied by September (ba2dc).