Skip to content

Commit 9145d36

Browse files
committed
paint colors in logical order and decomplicate
idk why I didn't use the measure function here; it made it more possible to paint in the wrong order. painting should always be in logical order!
1 parent 8b2550b commit 9145d36

File tree

2 files changed

+25
-24
lines changed

2 files changed

+25
-24
lines changed

src/paint.ts

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,54 +75,42 @@ function drawText(
7575
) {
7676
const style = item.attrs.style;
7777
const {textStart, textEnd} = getTextOffsetsForUncollapsedGlyphs(item);
78+
const state = item.createMeasureState();
7879
// Split the colors into spans so that colored diacritics can work.
7980
// Sadly this seems to only work in Firefox and only when the font doesn't do
8081
// any normalizination, so I could probably stop trying to support it
8182
// https://github.com/w3c/csswg-drafts/issues/699
82-
const end = item.attrs.level & 1 ? item.colorsStart(colors) - 1 : item.colorsEnd(colors);
83-
let i = item.attrs.level & 1 ? item.colorsEnd(colors) - 1 : item.colorsStart(colors);
84-
let glyphIndex = 0;
83+
const colorEnd = item.colorsEnd(colors);
84+
let colorIndex = item.colorsStart(colors);
8585
let tx = item.x;
8686

87-
while (i !== end) {
88-
const [color, offset] = colors[i];
87+
if (item.attrs.level & 1) tx += item.measure().advance;
88+
89+
while (colorIndex !== colorEnd) {
90+
const [color, offset] = colors[colorIndex];
8991
const colorStart = offset;
90-
const colorEnd = i + 1 < colors.length ? colors[i + 1][1] : textEnd;
92+
const colorEnd = colorIndex + 1 < colors.length ? colors[colorIndex + 1][1] : textEnd;
9193
const start = Math.max(colorStart, textStart);
9294
const end = Math.min(colorEnd, textEnd);
9395

9496
if (start < end) {
9597
// TODO: should really have isStartColorBoundary, isEndColorBoundary
9698
const isColorBoundary = start !== textStart && start === colorStart
9799
|| end !== textEnd && end === colorEnd;
98-
let ax = 0;
100+
const ax = item.measure(end, 1, state).advance;
99101

100-
if (item.attrs.level & 1) {
101-
while (glyphIndex < item.glyphs.length && item.glyphs[glyphIndex + G_CL] >= start) {
102-
ax += item.glyphs[glyphIndex + G_AX];
103-
glyphIndex += G_SZ;
104-
}
105-
} else {
106-
while (glyphIndex < item.glyphs.length && item.glyphs[glyphIndex + G_CL] < end) {
107-
ax += item.glyphs[glyphIndex + G_AX];
108-
glyphIndex += G_SZ;
109-
}
110-
}
102+
if (item.attrs.level & 1) tx -= ax;
111103

112104
b.fillColor = color;
113105
b.fontSize = style.fontSize;
114106
b.font = item.face;
115107
b.direction = item.attrs.level & 1 ? 'rtl' : 'ltr';
116108
b.text(tx, item.y, item, start, end, isColorBoundary);
117109

118-
tx += ax / item.face.hbface.upem * style.fontSize;
110+
if (!(item.attrs.level & 1)) tx += ax;
119111
}
120112

121-
if (item.attrs.level & 1) {
122-
i -= 1;
123-
} else {
124-
i += 1;
125-
}
113+
colorIndex += 1;
126114
}
127115
}
128116

test/paint.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,19 @@ describe('Painting', function () {
684684
unregisterFontAsset('NotoSansArabic/NotoSansArabic-Regular.ttf');
685685
});
686686

687+
it('paints colors in logical order', function () {
688+
this.layout(`
689+
<div style="font-size: 10px;">
690+
و<span style="color: #321;">التوابل</span>
691+
</div>
692+
`);
693+
694+
expect(this.paint().getCalls()).to.deep.equal([
695+
{t: 'text', x: 70, y: 8, text: 'و', fillColor: '#000'},
696+
{t: 'text', x: 0, y: 8, text: 'التوابل', fillColor: '#321'}
697+
]);
698+
});
699+
687700
// TODO: would go better in a general box.spec.js
688701
describe('Pixel snapping', function () {
689702
it('snaps the border box', function () {

0 commit comments

Comments
 (0)