render-tag 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -192
- package/lib/css-resolver.d.ts.map +1 -1
- package/lib/css-resolver.js +16 -0
- package/lib/css-resolver.js.map +1 -1
- package/lib/layout.d.ts.map +1 -1
- package/lib/layout.js +90 -0
- package/lib/layout.js.map +1 -1
- package/lib/path/glyph-layout.d.ts +63 -14
- package/lib/path/glyph-layout.d.ts.map +1 -1
- package/lib/path/glyph-layout.js +224 -42
- package/lib/path/glyph-layout.js.map +1 -1
- package/lib/path/index.d.ts +52 -17
- package/lib/path/index.d.ts.map +1 -1
- package/lib/path/index.js +314 -38
- package/lib/path/index.js.map +1 -1
- package/lib/render-tag.umd.js +4 -4
- package/lib/render-tag.umd.js.map +1 -1
- package/lib/render.d.ts +18 -0
- package/lib/render.d.ts.map +1 -1
- package/lib/render.js +3 -3
- package/lib/render.js.map +1 -1
- package/lib/types.d.ts +6 -0
- package/lib/types.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/path/index.js
CHANGED
|
@@ -13,22 +13,28 @@
|
|
|
13
13
|
* align: 'center',
|
|
14
14
|
* });
|
|
15
15
|
*
|
|
16
|
-
* For finer control
|
|
16
|
+
* For finer control:
|
|
17
17
|
* const result = layoutTextOnPath({ html, path, align });
|
|
18
18
|
* drawTextOnPathLayout({ layout: result, ctx });
|
|
19
|
-
* Use the split when you want to inspect / hit-test glyphs before drawing,
|
|
20
|
-
* or render the same layout onto multiple targets.
|
|
21
19
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
20
|
+
* Supported styles (matches the main renderer):
|
|
21
|
+
* font-family / size / weight / style / kerning
|
|
22
|
+
* color, -webkit-text-fill-color, -webkit-text-stroke (width + color), paint-order
|
|
23
|
+
* background-color (span backgrounds drawn as curve-following polygons)
|
|
24
|
+
* text-shadow (rotates with glyphs; multi-shadow supported)
|
|
25
|
+
* text-decoration: underline / line-through / overline (solid/dotted/dashed/double/wavy)
|
|
26
|
+
* text-decoration-color, text-decoration-style
|
|
27
|
+
* background-clip:text + background-image:linear-gradient (gradient flows along the path)
|
|
28
|
+
* letter-spacing, direction: rtl, dir="rtl"
|
|
29
|
+
* Arabic / Hebrew / Indic / Thai / Khmer / Myanmar — shaped runs are
|
|
30
|
+
* rendered as a unit so cursive joining and reordering work correctly.
|
|
26
31
|
*/
|
|
27
32
|
import { parseHTML } from '../parse.js';
|
|
28
|
-
import { resolveStylesFromCSS } from '../css-resolver.js';
|
|
29
|
-
import { applyFont } from '../layout.js';
|
|
33
|
+
import { resolveStylesFromCSS, paintOrderHasStrokeFirst } from '../css-resolver.js';
|
|
34
|
+
import { applyFont, isTransparent } from '../layout.js';
|
|
35
|
+
import { parseTextShadows, parseLinearGradient, drawDecorationLine, } from '../render.js';
|
|
30
36
|
import { pathFromString } from './svg-path.js';
|
|
31
|
-
import { flattenSegments, layoutGlyphsOnPath, } from './glyph-layout.js';
|
|
37
|
+
import { flattenSegments, layoutGlyphsOnPath, baselineLocalY, } from './glyph-layout.js';
|
|
32
38
|
/**
|
|
33
39
|
* Compute glyph placements for rich text along a path, without drawing.
|
|
34
40
|
* Useful for inspection, hit-testing, or rendering the same layout multiple times.
|
|
@@ -40,9 +46,8 @@ import { flattenSegments, layoutGlyphsOnPath, } from './glyph-layout.js';
|
|
|
40
46
|
* leaks to the caller.
|
|
41
47
|
*/
|
|
42
48
|
export function layoutTextOnPath(config) {
|
|
43
|
-
const { html, align = 'left' } = config;
|
|
49
|
+
const { html, align = 'left', textBaseline = 'alphabetic' } = config;
|
|
44
50
|
const path = typeof config.path === 'string' ? pathFromString(config.path) : config.path;
|
|
45
|
-
// Use the caller's ctx for measurement if given; otherwise spin up our own.
|
|
46
51
|
const measureCtx = config.ctx ?? createMeasureCtx();
|
|
47
52
|
const ownsCtx = config.ctx === undefined;
|
|
48
53
|
const { fragment, css } = parseHTML(html);
|
|
@@ -51,7 +56,7 @@ export function layoutTextOnPath(config) {
|
|
|
51
56
|
measureCtx.save();
|
|
52
57
|
try {
|
|
53
58
|
const segments = flattenSegments(tree);
|
|
54
|
-
return layoutGlyphsOnPath({ segments, path, ctx: measureCtx, align });
|
|
59
|
+
return layoutGlyphsOnPath({ segments, path, ctx: measureCtx, align, textBaseline });
|
|
55
60
|
}
|
|
56
61
|
finally {
|
|
57
62
|
if (!ownsCtx)
|
|
@@ -61,15 +66,25 @@ export function layoutTextOnPath(config) {
|
|
|
61
66
|
}
|
|
62
67
|
/**
|
|
63
68
|
* Draw a pre-computed layout onto a canvas context.
|
|
64
|
-
*
|
|
65
|
-
*
|
|
69
|
+
*
|
|
70
|
+
* Rendering passes (matching CSS painting order):
|
|
71
|
+
* 1. Span backgrounds (background-color, curve-following polygons)
|
|
72
|
+
* 2. Text shadows (per glyph, multi-shadow supported, rotates with glyph)
|
|
73
|
+
* 3. Glyph fill + stroke (paint-order aware; gradient text via slicing)
|
|
74
|
+
* 4. Text decoration (underline / line-through / overline)
|
|
75
|
+
*
|
|
76
|
+
* ctx state is saved+restored around the entire batch — nothing leaks.
|
|
66
77
|
*/
|
|
67
78
|
export function drawTextOnPathLayout(config) {
|
|
68
79
|
const { layout, ctx } = config;
|
|
80
|
+
if (layout.glyphs.length === 0)
|
|
81
|
+
return;
|
|
82
|
+
const tb = layout.textBaseline;
|
|
69
83
|
ctx.save();
|
|
70
84
|
try {
|
|
71
|
-
|
|
72
|
-
|
|
85
|
+
drawBackgrounds(ctx, layout.glyphs, tb);
|
|
86
|
+
drawShadowsAndGlyphs(ctx, layout.glyphs, layout.textWidth, tb);
|
|
87
|
+
drawDecorations(ctx, layout.glyphs, tb);
|
|
73
88
|
}
|
|
74
89
|
finally {
|
|
75
90
|
ctx.restore();
|
|
@@ -77,15 +92,13 @@ export function drawTextOnPathLayout(config) {
|
|
|
77
92
|
}
|
|
78
93
|
/**
|
|
79
94
|
* Convenience: compute layout and draw in a single call.
|
|
80
|
-
* Equivalent to `drawTextOnPathLayout({ layout: layoutTextOnPath(...), ctx })`.
|
|
81
95
|
*/
|
|
82
96
|
export function drawTextOnPath(config) {
|
|
83
|
-
// Save/restore is handled inside layoutTextOnPath + drawTextOnPathLayout,
|
|
84
|
-
// so the caller's ctx state survives both stages even when sharing one ctx.
|
|
85
97
|
const layout = layoutTextOnPath({
|
|
86
98
|
html: config.html,
|
|
87
99
|
path: config.path,
|
|
88
100
|
align: config.align,
|
|
101
|
+
textBaseline: config.textBaseline,
|
|
89
102
|
ctx: config.ctx,
|
|
90
103
|
});
|
|
91
104
|
drawTextOnPathLayout({ layout, ctx: config.ctx });
|
|
@@ -97,34 +110,187 @@ function createMeasureCtx() {
|
|
|
97
110
|
: document.createElement('canvas');
|
|
98
111
|
return canvas.getContext('2d');
|
|
99
112
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
113
|
+
// ─── Pass 1: Backgrounds ──────────────────────────────────────────────
|
|
114
|
+
/**
|
|
115
|
+
* Round-trip a color through `ctx.fillStyle` to get the browser's
|
|
116
|
+
* canonical form. This makes `red` and `rgb(255, 0, 0)` and `#f00`
|
|
117
|
+
* compare equal so adjacent spans with semantically-identical colors
|
|
118
|
+
* group into one polygon / one stroke (no visible seam, dash phase
|
|
119
|
+
* continuous). Results cached so we don't pay the round-trip per glyph.
|
|
120
|
+
*/
|
|
121
|
+
const _colorCanonicalCache = new WeakMap();
|
|
122
|
+
function canonicalColor(ctx, color) {
|
|
123
|
+
if (!color)
|
|
124
|
+
return '';
|
|
125
|
+
let perCtx = _colorCanonicalCache.get(ctx);
|
|
126
|
+
if (!perCtx) {
|
|
127
|
+
perCtx = new Map();
|
|
128
|
+
_colorCanonicalCache.set(ctx, perCtx);
|
|
129
|
+
}
|
|
130
|
+
const cached = perCtx.get(color);
|
|
131
|
+
if (cached !== undefined)
|
|
132
|
+
return cached;
|
|
133
|
+
// ctx.fillStyle returns the canonical form when read back.
|
|
134
|
+
const prev = ctx.fillStyle;
|
|
135
|
+
try {
|
|
136
|
+
ctx.fillStyle = color;
|
|
137
|
+
const canon = typeof ctx.fillStyle === 'string' ? ctx.fillStyle : color;
|
|
138
|
+
perCtx.set(color, canon);
|
|
139
|
+
return canon;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
perCtx.set(color, color);
|
|
143
|
+
return color;
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
ctx.fillStyle = prev;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Group consecutive glyphs sharing a visible background color and draw each
|
|
151
|
+
* group as a curve-following polygon (top edge + bottom edge).
|
|
152
|
+
*/
|
|
153
|
+
function drawBackgrounds(ctx, glyphs, tb) {
|
|
154
|
+
let i = 0;
|
|
155
|
+
while (i < glyphs.length) {
|
|
156
|
+
const bg = glyphs[i].style.backgroundColor;
|
|
157
|
+
if (!bg || isTransparent(bg)) {
|
|
158
|
+
i++;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const canon = canonicalColor(ctx, bg);
|
|
162
|
+
let j = i + 1;
|
|
163
|
+
while (j < glyphs.length &&
|
|
164
|
+
canonicalColor(ctx, glyphs[j].style.backgroundColor) === canon)
|
|
165
|
+
j++;
|
|
166
|
+
fillGlyphPolygon(ctx, glyphs.slice(i, j), bg, tb);
|
|
167
|
+
i = j;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Build the four-corner box of one glyph in world coordinates. Local y=0 is
|
|
172
|
+
* the path point — actual baseline sits at `baselineLocalY(tb, ascent, descent)`.
|
|
173
|
+
* The polygon spans `[baseY - ascent, baseY + descent]` so it hugs the painted
|
|
174
|
+
* glyph extent regardless of which textBaseline anchor was chosen.
|
|
175
|
+
*/
|
|
176
|
+
function glyphCorners(g, tb) {
|
|
177
|
+
const c = Math.cos(g.rotation);
|
|
178
|
+
const s = Math.sin(g.rotation);
|
|
179
|
+
const baseY = baselineLocalY(tb, g.ascent, g.descent);
|
|
180
|
+
const top = baseY - g.ascent;
|
|
181
|
+
const bottom = baseY + g.descent;
|
|
182
|
+
const w = g.width;
|
|
183
|
+
return {
|
|
184
|
+
tl: { x: g.x + (-s) * top, y: g.y + c * top },
|
|
185
|
+
tr: { x: g.x + c * w + (-s) * top, y: g.y + s * w + c * top },
|
|
186
|
+
br: { x: g.x + c * w + (-s) * bottom, y: g.y + s * w + c * bottom },
|
|
187
|
+
bl: { x: g.x + (-s) * bottom, y: g.y + c * bottom },
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/** Fill a polygon hugging the path through a sequence of consecutive glyphs. */
|
|
191
|
+
function fillGlyphPolygon(ctx, group, fill, tb) {
|
|
192
|
+
if (group.length === 0)
|
|
193
|
+
return;
|
|
103
194
|
ctx.save();
|
|
104
|
-
ctx.
|
|
105
|
-
ctx.
|
|
106
|
-
|
|
107
|
-
ctx.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
195
|
+
ctx.fillStyle = fill;
|
|
196
|
+
ctx.beginPath();
|
|
197
|
+
const first = glyphCorners(group[0], tb);
|
|
198
|
+
ctx.moveTo(first.tl.x, first.tl.y);
|
|
199
|
+
for (let i = 0; i < group.length; i++) {
|
|
200
|
+
const c = glyphCorners(group[i], tb);
|
|
201
|
+
ctx.lineTo(c.tl.x, c.tl.y);
|
|
202
|
+
ctx.lineTo(c.tr.x, c.tr.y);
|
|
203
|
+
}
|
|
204
|
+
for (let i = group.length - 1; i >= 0; i--) {
|
|
205
|
+
const c = glyphCorners(group[i], tb);
|
|
206
|
+
ctx.lineTo(c.br.x, c.br.y);
|
|
207
|
+
ctx.lineTo(c.bl.x, c.bl.y);
|
|
208
|
+
}
|
|
209
|
+
ctx.closePath();
|
|
210
|
+
ctx.fill();
|
|
211
|
+
ctx.restore();
|
|
212
|
+
}
|
|
213
|
+
// ─── Pass 2: Shadows + glyph fill/stroke ─────────────────────────────
|
|
214
|
+
/**
|
|
215
|
+
* Iterate glyphs once. For each: draw the configured text-shadow stack (if
|
|
216
|
+
* any), then fill (possibly through a sliced gradient) and stroke per
|
|
217
|
+
* paint-order.
|
|
218
|
+
*/
|
|
219
|
+
function drawShadowsAndGlyphs(ctx, glyphs, textWidth, tb) {
|
|
220
|
+
for (const g of glyphs) {
|
|
221
|
+
ctx.save();
|
|
222
|
+
ctx.translate(g.x, g.y);
|
|
223
|
+
ctx.rotate(g.rotation);
|
|
224
|
+
applyFont(ctx, g.style);
|
|
225
|
+
// Keep ctx.textBaseline at 'alphabetic' and offset fillText's y instead.
|
|
226
|
+
// This keeps our bounds / decoration / background math in agreement with
|
|
227
|
+
// what fillText actually paints, regardless of which textBaseline the
|
|
228
|
+
// caller picked.
|
|
229
|
+
ctx.textBaseline = 'alphabetic';
|
|
230
|
+
// Mirror the letter-spacing used at measurement time. Without this,
|
|
231
|
+
// shaped runs (Arabic / Indic / Thai) whose `g.width` was measured WITH
|
|
232
|
+
// letter-spacing render visibly tighter than the reserved width.
|
|
233
|
+
// Always assign so a stale value from earlier glyphs doesn't leak.
|
|
234
|
+
ctx.letterSpacing = `${g.style.letterSpacing || 0}px`;
|
|
235
|
+
const baseY = baselineLocalY(tb, g.ascent, g.descent);
|
|
236
|
+
// Shadow pass — drawn underneath the glyph fill. Multi-shadow stacks
|
|
237
|
+
// paint last-listed-first so the first declared shadow is on top.
|
|
238
|
+
const shadows = parseTextShadows(g.style.textShadow);
|
|
239
|
+
if (shadows.length > 0) {
|
|
240
|
+
for (let i = shadows.length - 1; i >= 0; i--) {
|
|
241
|
+
const sh = shadows[i];
|
|
242
|
+
ctx.save();
|
|
243
|
+
ctx.shadowOffsetX = sh.offsetX;
|
|
244
|
+
ctx.shadowOffsetY = sh.offsetY;
|
|
245
|
+
ctx.shadowBlur = sh.blur;
|
|
246
|
+
ctx.shadowColor = sh.color;
|
|
247
|
+
ctx.fillStyle = effectiveFillColor(g.style);
|
|
248
|
+
ctx.fillText(g.char, 0, baseY);
|
|
249
|
+
ctx.restore();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
drawGlyphFillAndStroke(ctx, g, textWidth, baseY);
|
|
253
|
+
ctx.restore();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function drawGlyphFillAndStroke(ctx, g, textWidth, baseY) {
|
|
257
|
+
const { style } = g;
|
|
258
|
+
// Mirror the main renderer's transparency check: EITHER -webkit-text-fill-color
|
|
259
|
+
// or color being 'transparent' suppresses the fill. effectiveFillColor alone
|
|
260
|
+
// would only catch one of the two by falling back through the precedence.
|
|
261
|
+
const fillTransparent = style.webkitTextFillColor === 'transparent' ||
|
|
262
|
+
style.color === 'transparent' ||
|
|
263
|
+
isTransparent(effectiveFillColor(style));
|
|
111
264
|
const isStroked = style.webkitTextStrokeWidth > 0;
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
265
|
+
const usesGradient = style.webkitBackgroundClip === 'text' &&
|
|
266
|
+
style.backgroundImage && style.backgroundImage !== 'none';
|
|
267
|
+
// Use the canonical helper instead of an ad-hoc regex — paint-order tokens
|
|
268
|
+
// are positional ("fill stroke" = fill first), not a flag bag.
|
|
269
|
+
const paintStrokeFirst = paintOrderHasStrokeFirst(style.paintOrder || '');
|
|
115
270
|
const drawFill = () => {
|
|
116
|
-
if (
|
|
271
|
+
if (usesGradient) {
|
|
272
|
+
drawGradientGlyph(ctx, g, textWidth, baseY);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (fillTransparent) {
|
|
276
|
+
if (isStroked)
|
|
277
|
+
return;
|
|
278
|
+
ctx.fillStyle = 'transparent';
|
|
279
|
+
ctx.fillText(g.char, 0, baseY);
|
|
117
280
|
return;
|
|
118
|
-
|
|
119
|
-
ctx.
|
|
281
|
+
}
|
|
282
|
+
ctx.fillStyle = effectiveFillColor(style);
|
|
283
|
+
ctx.fillText(g.char, 0, baseY);
|
|
120
284
|
};
|
|
121
285
|
const drawStroke = () => {
|
|
122
286
|
if (!isStroked)
|
|
123
287
|
return;
|
|
288
|
+
ctx.save();
|
|
124
289
|
ctx.lineJoin = 'round';
|
|
125
290
|
ctx.lineWidth = style.webkitTextStrokeWidth;
|
|
126
291
|
ctx.strokeStyle = style.webkitTextStrokeColor || style.color;
|
|
127
|
-
ctx.strokeText(g.char, 0,
|
|
292
|
+
ctx.strokeText(g.char, 0, baseY);
|
|
293
|
+
ctx.restore();
|
|
128
294
|
};
|
|
129
295
|
if (paintStrokeFirst) {
|
|
130
296
|
drawStroke();
|
|
@@ -134,9 +300,119 @@ function drawGlyph(ctx, g) {
|
|
|
134
300
|
drawFill();
|
|
135
301
|
drawStroke();
|
|
136
302
|
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Render one glyph with a gradient fill that flows along the path. The
|
|
306
|
+
* gradient is created once per glyph spanning the FULL text width in the
|
|
307
|
+
* glyph's local rotated frame, offset so the glyph's slice lines up with
|
|
308
|
+
* the global gradient. Neighbouring glyphs stitch into one continuous color
|
|
309
|
+
* curve when viewed along the path.
|
|
310
|
+
*/
|
|
311
|
+
function drawGradientGlyph(ctx, g, textWidth, baseY) {
|
|
312
|
+
// The gradient is laid out from (-pathOffset, *) to (textWidth-pathOffset, *)
|
|
313
|
+
// in this glyph's local frame, so global gradient at fraction t/textWidth
|
|
314
|
+
// matches what neighbouring glyphs render. The vertical band tracks the
|
|
315
|
+
// glyph's full extent around the baseline anchor.
|
|
316
|
+
const gradient = parseLinearGradient(ctx, g.style.backgroundImage, -g.pathOffset, textWidth, baseY - g.ascent, g.ascent + g.descent);
|
|
317
|
+
if (!gradient) {
|
|
318
|
+
ctx.fillStyle = effectiveFillColor(g.style);
|
|
319
|
+
ctx.fillText(g.char, 0, baseY);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
ctx.fillStyle = gradient;
|
|
323
|
+
ctx.fillText(g.char, 0, baseY);
|
|
324
|
+
}
|
|
325
|
+
// ─── Pass 3: Decorations ─────────────────────────────────────────────
|
|
326
|
+
/**
|
|
327
|
+
* Underline / line-through / overline: stroke a curve that follows the path
|
|
328
|
+
* at the appropriate vertical offset. Groups consecutive glyphs sharing
|
|
329
|
+
* decoration-line + style + color.
|
|
330
|
+
*/
|
|
331
|
+
function drawDecorations(ctx, glyphs, tb) {
|
|
332
|
+
const lines = ['underline', 'line-through', 'overline'];
|
|
333
|
+
for (const lineKind of lines) {
|
|
334
|
+
let i = 0;
|
|
335
|
+
while (i < glyphs.length) {
|
|
336
|
+
const style = glyphs[i].style;
|
|
337
|
+
if (!style.textDecorationLine || !style.textDecorationLine.includes(lineKind)) {
|
|
338
|
+
i++;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
const color = style.textDecorationColor || style.color;
|
|
342
|
+
const decoStyle = style.textDecorationStyle || 'solid';
|
|
343
|
+
const colorCanon = canonicalColor(ctx, color);
|
|
344
|
+
let j = i + 1;
|
|
345
|
+
while (j < glyphs.length &&
|
|
346
|
+
glyphs[j].style.textDecorationLine &&
|
|
347
|
+
glyphs[j].style.textDecorationLine.includes(lineKind) &&
|
|
348
|
+
canonicalColor(ctx, glyphs[j].style.textDecorationColor || glyphs[j].style.color) === colorCanon &&
|
|
349
|
+
(glyphs[j].style.textDecorationStyle || 'solid') === decoStyle)
|
|
350
|
+
j++;
|
|
351
|
+
strokeDecorationAlongGlyphs(ctx, glyphs.slice(i, j), lineKind, decoStyle, color, tb);
|
|
352
|
+
i = j;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function strokeDecorationAlongGlyphs(ctx, group, lineKind, decoStyle, color, tb) {
|
|
357
|
+
if (group.length === 0)
|
|
358
|
+
return;
|
|
359
|
+
const lineWidth = Math.max(1, group[0].style.fontSize / 15);
|
|
360
|
+
// Per-glyph local y for this decoration kind. The decoration position is
|
|
361
|
+
// baseline-relative, so we shift by the baseline's local-y under the
|
|
362
|
+
// current textBaseline to land in the right spot on the canvas.
|
|
363
|
+
const localY = (g) => {
|
|
364
|
+
const baseY = baselineLocalY(tb, g.ascent, g.descent);
|
|
365
|
+
if (lineKind === 'underline')
|
|
366
|
+
return baseY + g.descent * 0.5;
|
|
367
|
+
if (lineKind === 'line-through')
|
|
368
|
+
return baseY - g.ascent * 0.3;
|
|
369
|
+
return baseY - g.ascent * 0.9; // overline
|
|
370
|
+
};
|
|
371
|
+
if (decoStyle === 'double' || decoStyle === 'wavy') {
|
|
372
|
+
// For double/wavy we draw each glyph segment independently using the
|
|
373
|
+
// shared helper so the visual matches the main renderer.
|
|
374
|
+
for (const g of group) {
|
|
375
|
+
ctx.save();
|
|
376
|
+
ctx.translate(g.x, g.y);
|
|
377
|
+
ctx.rotate(g.rotation);
|
|
378
|
+
drawDecorationLine(ctx, 0, localY(g), g.width, lineWidth, decoStyle, color);
|
|
379
|
+
ctx.restore();
|
|
380
|
+
}
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
// Solid / dotted / dashed: a single continuous polyline through (left,
|
|
384
|
+
// right) endpoints of each glyph projected into world space. Stroking
|
|
385
|
+
// once keeps the dash phase continuous across the whole decoration run.
|
|
386
|
+
ctx.save();
|
|
387
|
+
ctx.strokeStyle = color;
|
|
388
|
+
ctx.lineWidth = lineWidth;
|
|
389
|
+
if (decoStyle === 'dotted')
|
|
390
|
+
ctx.setLineDash([lineWidth, lineWidth * 2]);
|
|
391
|
+
else if (decoStyle === 'dashed')
|
|
392
|
+
ctx.setLineDash([lineWidth * 3, lineWidth * 2]);
|
|
393
|
+
ctx.beginPath();
|
|
394
|
+
for (let i = 0; i < group.length; i++) {
|
|
395
|
+
const g = group[i];
|
|
396
|
+
const yOff = localY(g);
|
|
397
|
+
const c = Math.cos(g.rotation);
|
|
398
|
+
const s = Math.sin(g.rotation);
|
|
399
|
+
const left = { x: g.x + (-s) * yOff, y: g.y + c * yOff };
|
|
400
|
+
const right = {
|
|
401
|
+
x: g.x + c * g.width + (-s) * yOff,
|
|
402
|
+
y: g.y + s * g.width + c * yOff,
|
|
403
|
+
};
|
|
404
|
+
if (i === 0)
|
|
405
|
+
ctx.moveTo(left.x, left.y);
|
|
406
|
+
else
|
|
407
|
+
ctx.lineTo(left.x, left.y);
|
|
408
|
+
ctx.lineTo(right.x, right.y);
|
|
409
|
+
}
|
|
410
|
+
ctx.stroke();
|
|
411
|
+
ctx.setLineDash([]);
|
|
137
412
|
ctx.restore();
|
|
138
413
|
}
|
|
139
|
-
|
|
414
|
+
// ─── Style helpers ───────────────────────────────────────────────────
|
|
415
|
+
function effectiveFillColor(style) {
|
|
140
416
|
if (style.webkitTextFillColor && style.webkitTextFillColor !== 'transparent') {
|
|
141
417
|
return style.webkitTextFillColor;
|
|
142
418
|
}
|
package/lib/path/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/path/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/path/index.ts"],"names":[],"mappings":"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"}
|