postext 1.29.2 → 1.30.0
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/dist/__tests__/arabicLocale.test.js +5 -5
- package/dist/__tests__/arabicLocale.test.js.map +1 -1
- package/dist/__tests__/bundle/balloonPlacementPin.test.js +5 -4
- package/dist/__tests__/bundle/balloonPlacementPin.test.js.map +1 -1
- package/dist/__tests__/bundle/cjkRulesPin.test.js +8 -6
- package/dist/__tests__/bundle/cjkRulesPin.test.js.map +1 -1
- package/dist/__tests__/bundle/designOverflowPin.test.js +1 -1
- package/dist/__tests__/bundle/flowColumnsPin.test.js +4 -3
- package/dist/__tests__/bundle/flowColumnsPin.test.js.map +1 -1
- package/dist/__tests__/bundle/gridBalancingPin.test.js +5 -4
- package/dist/__tests__/bundle/gridBalancingPin.test.js.map +1 -1
- package/dist/__tests__/bundle/gridBreakRulesPin.test.js +14 -10
- package/dist/__tests__/bundle/gridBreakRulesPin.test.js.map +1 -1
- package/dist/__tests__/bundle/indexGroupSplitPin.test.js +4 -3
- package/dist/__tests__/bundle/indexGroupSplitPin.test.js.map +1 -1
- package/dist/__tests__/bundle/looseOrderPin.test.js +5 -4
- package/dist/__tests__/bundle/looseOrderPin.test.js.map +1 -1
- package/dist/__tests__/bundle/refLabelBreaksPin.test.js +5 -4
- package/dist/__tests__/bundle/refLabelBreaksPin.test.js.map +1 -1
- package/dist/__tests__/bundle/scriptContextPin.test.js +6 -5
- package/dist/__tests__/bundle/scriptContextPin.test.js.map +1 -1
- package/dist/__tests__/bundle/shapingLanguagePin.test.js +142 -46
- package/dist/__tests__/bundle/shapingLanguagePin.test.js.map +1 -1
- package/dist/__tests__/bundle/taskBoxPin.test.js +1 -1
- package/dist/__tests__/bundle/trailingStepPin.test.js +4 -3
- package/dist/__tests__/bundle/trailingStepPin.test.js.map +1 -1
- package/dist/__tests__/bundle/wideFloatStretchPin.test.js +4 -3
- package/dist/__tests__/bundle/wideFloatStretchPin.test.js.map +1 -1
- package/dist/__tests__/bundle.test.js +1 -1
- package/dist/__tests__/cellText.test.d.ts +2 -0
- package/dist/__tests__/cellText.test.d.ts.map +1 -0
- package/dist/__tests__/cellText.test.js +281 -0
- package/dist/__tests__/cellText.test.js.map +1 -0
- package/dist/__tests__/chineseLocale.test.js +13 -11
- package/dist/__tests__/chineseLocale.test.js.map +1 -1
- package/dist/__tests__/cjk/japaneseHtml.test.js +3 -3
- package/dist/__tests__/cjk/japaneseHtml.test.js.map +1 -1
- package/dist/__tests__/cjk/japaneseRuby.test.js +1 -1
- package/dist/__tests__/cjk/japaneseRuby.test.js.map +1 -1
- package/dist/__tests__/cjk/japaneseSegmentLanguage.test.js +3 -3
- package/dist/__tests__/cjk/japaneseSegmentLanguage.test.js.map +1 -1
- package/dist/__tests__/codeBlocks.test.js +1 -1
- package/dist/__tests__/contextText.test.d.ts +2 -0
- package/dist/__tests__/contextText.test.d.ts.map +1 -0
- package/dist/__tests__/contextText.test.js +371 -0
- package/dist/__tests__/contextText.test.js.map +1 -0
- package/dist/__tests__/design/designTextRender.test.js +8 -1
- package/dist/__tests__/design/designTextRender.test.js.map +1 -1
- package/dist/__tests__/exports.test.js +6 -0
- package/dist/__tests__/exports.test.js.map +1 -1
- package/dist/__tests__/fontUsage.test.js +40 -0
- package/dist/__tests__/fontUsage.test.js.map +1 -1
- package/dist/__tests__/hardBreaks.test.js +1 -1
- package/dist/__tests__/headingInlineMarks.test.js +1 -1
- package/dist/__tests__/html-backend.test.js +6 -2
- package/dist/__tests__/html-backend.test.js.map +1 -1
- package/dist/__tests__/japaneseNotes.test.js +4 -2
- package/dist/__tests__/japaneseNotes.test.js.map +1 -1
- package/dist/__tests__/lineEndPieces.test.d.ts +2 -0
- package/dist/__tests__/lineEndPieces.test.d.ts.map +1 -0
- package/dist/__tests__/lineEndPieces.test.js +374 -0
- package/dist/__tests__/lineEndPieces.test.js.map +1 -0
- package/dist/__tests__/mathSizeMigration.test.js +2 -2
- package/dist/__tests__/pipeline/calloutInlineResourceGap.test.js +1 -1
- package/dist/__tests__/pipeline/calloutSplitMinLinesChild.test.js +1 -1
- package/dist/__tests__/pipeline/colonListRoom.test.js +1 -1
- package/dist/__tests__/pipeline/compoundBreaks.test.js +1 -1
- package/dist/__tests__/pipeline/dashBreaks.test.js +1 -1
- package/dist/__tests__/pipeline/headingSplitOrphans.test.js +1 -1
- package/dist/__tests__/pipeline/inlineFigureSpace.test.js +1 -1
- package/dist/__tests__/pipeline/paragraphContainerTail.test.js +1 -1
- package/dist/__tests__/pipeline/raggedOptimal.test.js +1 -1
- package/dist/__tests__/plainGeminateHead.test.d.ts +2 -0
- package/dist/__tests__/plainGeminateHead.test.d.ts.map +1 -0
- package/dist/__tests__/plainGeminateHead.test.js +92 -0
- package/dist/__tests__/plainGeminateHead.test.js.map +1 -0
- package/dist/__tests__/presets/showcaseShapingLanguage.test.d.ts +2 -0
- package/dist/__tests__/presets/showcaseShapingLanguage.test.d.ts.map +1 -0
- package/dist/__tests__/presets/showcaseShapingLanguage.test.js +52 -0
- package/dist/__tests__/presets/showcaseShapingLanguage.test.js.map +1 -0
- package/dist/__tests__/reshapedTracking.test.d.ts +2 -0
- package/dist/__tests__/reshapedTracking.test.d.ts.map +1 -0
- package/dist/__tests__/reshapedTracking.test.js +358 -0
- package/dist/__tests__/reshapedTracking.test.js.map +1 -0
- package/dist/__tests__/rtl/designRunsPainted.test.d.ts +2 -0
- package/dist/__tests__/rtl/designRunsPainted.test.d.ts.map +1 -0
- package/dist/__tests__/rtl/designRunsPainted.test.js +184 -0
- package/dist/__tests__/rtl/designRunsPainted.test.js.map +1 -0
- package/dist/__tests__/rtl/designTextPaint.test.js +5 -1
- package/dist/__tests__/rtl/designTextPaint.test.js.map +1 -1
- package/dist/__tests__/rtl/htmlRtl.test.js +3 -3
- package/dist/__tests__/rtl/htmlRtl.test.js.map +1 -1
- package/dist/__tests__/rtl/listMarkerDirection.test.js +28 -28
- package/dist/__tests__/rtl/listMarkerDirection.test.js.map +1 -1
- package/dist/__tests__/rtl/tocNumberPainted.test.d.ts +2 -0
- package/dist/__tests__/rtl/tocNumberPainted.test.d.ts.map +1 -0
- package/dist/__tests__/rtl/tocNumberPainted.test.js +113 -0
- package/dist/__tests__/rtl/tocNumberPainted.test.js.map +1 -0
- package/dist/__tests__/scriptContext.test.js +141 -1
- package/dist/__tests__/scriptContext.test.js.map +1 -1
- package/dist/__tests__/shapingLanguage.test.js +54 -41
- package/dist/__tests__/shapingLanguage.test.js.map +1 -1
- package/dist/__tests__/trackedLetters.test.d.ts +2 -0
- package/dist/__tests__/trackedLetters.test.d.ts.map +1 -0
- package/dist/__tests__/trackedLetters.test.js +380 -0
- package/dist/__tests__/trackedLetters.test.js.map +1 -0
- package/dist/__tests__/trackedLigatures.test.js +17 -5
- package/dist/__tests__/trackedLigatures.test.js.map +1 -1
- package/dist/__tests__/verseLines.test.js +1 -1
- package/dist/__tests__/wordCacheOrder.test.d.ts +2 -0
- package/dist/__tests__/wordCacheOrder.test.d.ts.map +1 -0
- package/dist/__tests__/wordCacheOrder.test.js +352 -0
- package/dist/__tests__/wordCacheOrder.test.js.map +1 -0
- package/dist/__tests__/wordPieces.test.d.ts +2 -0
- package/dist/__tests__/wordPieces.test.d.ts.map +1 -0
- package/dist/__tests__/wordPieces.test.js +762 -0
- package/dist/__tests__/wordPieces.test.js.map +1 -0
- package/dist/bidi.d.ts +12 -0
- package/dist/bidi.d.ts.map +1 -1
- package/dist/bidi.js +23 -0
- package/dist/bidi.js.map +1 -1
- package/dist/bundle/configVersion.d.ts +49 -23
- package/dist/bundle/configVersion.d.ts.map +1 -1
- package/dist/bundle/configVersion.js +54 -25
- package/dist/bundle/configVersion.js.map +1 -1
- package/dist/canvas-backend/blockRender.d.ts.map +1 -1
- package/dist/canvas-backend/blockRender.js +58 -27
- package/dist/canvas-backend/blockRender.js.map +1 -1
- package/dist/canvas-backend/cellText.d.ts +12 -0
- package/dist/canvas-backend/cellText.d.ts.map +1 -0
- package/dist/canvas-backend/cellText.js +114 -0
- package/dist/canvas-backend/cellText.js.map +1 -0
- package/dist/canvas-backend/chip.d.ts.map +1 -1
- package/dist/canvas-backend/chip.js +2 -1
- package/dist/canvas-backend/chip.js.map +1 -1
- package/dist/canvas-backend/contextState.d.ts +7 -0
- package/dist/canvas-backend/contextState.d.ts.map +1 -1
- package/dist/canvas-backend/contextState.js +7 -0
- package/dist/canvas-backend/contextState.js.map +1 -1
- package/dist/canvas-backend/contextText.d.ts +76 -0
- package/dist/canvas-backend/contextText.d.ts.map +1 -0
- package/dist/canvas-backend/contextText.js +102 -0
- package/dist/canvas-backend/contextText.js.map +1 -0
- package/dist/canvas-backend/headerFooter.d.ts.map +1 -1
- package/dist/canvas-backend/headerFooter.js +8 -1
- package/dist/canvas-backend/headerFooter.js.map +1 -1
- package/dist/canvas-backend/index.d.ts.map +1 -1
- package/dist/canvas-backend/index.js +19 -13
- package/dist/canvas-backend/index.js.map +1 -1
- package/dist/canvas-backend/renderResourceBlock.d.ts.map +1 -1
- package/dist/canvas-backend/renderResourceBlock.js +12 -6
- package/dist/canvas-backend/renderResourceBlock.js.map +1 -1
- package/dist/canvas-backend/scriptText.d.ts.map +1 -1
- package/dist/canvas-backend/scriptText.js +3 -2
- package/dist/canvas-backend/scriptText.js.map +1 -1
- package/dist/canvas-backend/segmentText.d.ts.map +1 -1
- package/dist/canvas-backend/segmentText.js +8 -2
- package/dist/canvas-backend/segmentText.js.map +1 -1
- package/dist/canvas-backend/trackedText.d.ts +75 -1
- package/dist/canvas-backend/trackedText.d.ts.map +1 -1
- package/dist/canvas-backend/trackedText.js +185 -22
- package/dist/canvas-backend/trackedText.js.map +1 -1
- package/dist/canvas-backend/verticalText.d.ts +9 -0
- package/dist/canvas-backend/verticalText.d.ts.map +1 -1
- package/dist/canvas-backend/verticalText.js +29 -7
- package/dist/canvas-backend/verticalText.js.map +1 -1
- package/dist/canvas-backend/wordPieces.d.ts +31 -0
- package/dist/canvas-backend/wordPieces.d.ts.map +1 -0
- package/dist/canvas-backend/wordPieces.js +132 -0
- package/dist/canvas-backend/wordPieces.js.map +1 -0
- package/dist/canvas-backend/wordRuns.d.ts +3 -1
- package/dist/canvas-backend/wordRuns.d.ts.map +1 -1
- package/dist/canvas-backend/wordRuns.js +10 -6
- package/dist/canvas-backend/wordRuns.js.map +1 -1
- package/dist/comics/lettering/__tests__/fitAsPainted.test.d.ts +2 -0
- package/dist/comics/lettering/__tests__/fitAsPainted.test.d.ts.map +1 -0
- package/dist/comics/lettering/__tests__/fitAsPainted.test.js +97 -0
- package/dist/comics/lettering/__tests__/fitAsPainted.test.js.map +1 -0
- package/dist/comics/lettering/shape-text.d.ts.map +1 -1
- package/dist/comics/lettering/shape-text.js +39 -11
- package/dist/comics/lettering/shape-text.js.map +1 -1
- package/dist/defaults/bodyText.d.ts.map +1 -1
- package/dist/defaults/bodyText.js +6 -5
- package/dist/defaults/bodyText.js.map +1 -1
- package/dist/design/bidiText.d.ts +45 -6
- package/dist/design/bidiText.d.ts.map +1 -1
- package/dist/design/bidiText.js +78 -10
- package/dist/design/bidiText.js.map +1 -1
- package/dist/design/cjkText.d.ts +3 -0
- package/dist/design/cjkText.d.ts.map +1 -1
- package/dist/design/cjkText.js +1 -1
- package/dist/design/cjkText.js.map +1 -1
- package/dist/design/layout.d.ts.map +1 -1
- package/dist/design/layout.js +36 -5
- package/dist/design/layout.js.map +1 -1
- package/dist/design/richText.d.ts +9 -1
- package/dist/design/richText.d.ts.map +1 -1
- package/dist/design/richText.js +8 -2
- package/dist/design/richText.js.map +1 -1
- package/dist/fonts/usage.d.ts +2 -0
- package/dist/fonts/usage.d.ts.map +1 -1
- package/dist/fonts/usage.js +18 -0
- package/dist/fonts/usage.js.map +1 -1
- package/dist/html-backend.d.ts.map +1 -1
- package/dist/html-backend.js +664 -84
- package/dist/html-backend.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/knuthPlass/breakpoints.d.ts.map +1 -1
- package/dist/knuthPlass/breakpoints.js +4 -2
- package/dist/knuthPlass/breakpoints.js.map +1 -1
- package/dist/knuthPlass/pretextAdapter.d.ts +6 -3
- package/dist/knuthPlass/pretextAdapter.d.ts.map +1 -1
- package/dist/knuthPlass/pretextAdapter.js +11 -3
- package/dist/knuthPlass/pretextAdapter.js.map +1 -1
- package/dist/knuthPlass/richAdapter.d.ts +13 -1
- package/dist/knuthPlass/richAdapter.d.ts.map +1 -1
- package/dist/knuthPlass/richAdapter.js +53 -5
- package/dist/knuthPlass/richAdapter.js.map +1 -1
- package/dist/knuthPlass/tracking.d.ts.map +1 -1
- package/dist/knuthPlass/tracking.js +3 -2
- package/dist/knuthPlass/tracking.js.map +1 -1
- package/dist/knuthPlass/types.d.ts +6 -0
- package/dist/knuthPlass/types.d.ts.map +1 -1
- package/dist/locale.d.ts +21 -17
- package/dist/locale.d.ts.map +1 -1
- package/dist/locale.js +23 -19
- package/dist/locale.js.map +1 -1
- package/dist/measure/canvas.d.ts +21 -0
- package/dist/measure/canvas.d.ts.map +1 -1
- package/dist/measure/canvas.js +165 -85
- package/dist/measure/canvas.js.map +1 -1
- package/dist/measure/cjkCompose.d.ts.map +1 -1
- package/dist/measure/cjkCompose.js +31 -5
- package/dist/measure/cjkCompose.js.map +1 -1
- package/dist/measure/plain.d.ts.map +1 -1
- package/dist/measure/plain.js +31 -6
- package/dist/measure/plain.js.map +1 -1
- package/dist/measure/pretextLanguage.d.ts.map +1 -1
- package/dist/measure/pretextLanguage.js +49 -7
- package/dist/measure/pretextLanguage.js.map +1 -1
- package/dist/measure/rich.d.ts +18 -1
- package/dist/measure/rich.d.ts.map +1 -1
- package/dist/measure/rich.js +200 -29
- package/dist/measure/rich.js.map +1 -1
- package/dist/measure/script.d.ts +17 -1
- package/dist/measure/script.d.ts.map +1 -1
- package/dist/measure/script.js +17 -1
- package/dist/measure/script.js.map +1 -1
- package/dist/measure/trackedLigatures.d.ts +59 -0
- package/dist/measure/trackedLigatures.d.ts.map +1 -0
- package/dist/measure/trackedLigatures.js +144 -0
- package/dist/measure/trackedLigatures.js.map +1 -0
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +4 -3
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/calloutLayout.d.ts.map +1 -1
- package/dist/pipeline/calloutLayout.js +26 -7
- package/dist/pipeline/calloutLayout.js.map +1 -1
- package/dist/pipeline/lists.d.ts +13 -4
- package/dist/pipeline/lists.d.ts.map +1 -1
- package/dist/pipeline/lists.js +49 -12
- package/dist/pipeline/lists.js.map +1 -1
- package/dist/pipeline/toc.d.ts.map +1 -1
- package/dist/pipeline/toc.js +33 -9
- package/dist/pipeline/toc.js.map +1 -1
- package/dist/types.d.ts +35 -26
- package/dist/types.d.ts.map +1 -1
- package/dist/wordPieces.d.ts +120 -0
- package/dist/wordPieces.d.ts.map +1 -0
- package/dist/wordPieces.js +319 -0
- package/dist/wordPieces.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { lineWordSegmentsInOrder, sameSetWidth } from '../wordPieces';
|
|
2
|
+
import { graphemeCount } from '../measure/graphemes';
|
|
3
|
+
import { measurementGeneration } from '../measure/canvas';
|
|
4
|
+
import { languageOf, setLetterSpacing } from './contextState';
|
|
5
|
+
import { inSegmentLanguage } from './wordRuns';
|
|
6
|
+
import { contextTextWidth } from './contextText';
|
|
7
|
+
import { verticalFlowAdvance } from './verticalText';
|
|
8
|
+
/** A line's segments → what is known of the line. */
|
|
9
|
+
const painted = new WeakMap();
|
|
10
|
+
/** What is known of the line of `segments` under the faces loaded, the
|
|
11
|
+
* language and the `tracking` painted in and the line's `font`, with its
|
|
12
|
+
* segments as they are; nothing yet when any of those changed. */
|
|
13
|
+
function knownOf(ctx, line, segments, tracking, font) {
|
|
14
|
+
let widths = 0;
|
|
15
|
+
for (const seg of segments)
|
|
16
|
+
widths += seg.width;
|
|
17
|
+
const key = `${measurementGeneration()}\u0000${languageOf(ctx) ?? ''}\u0000${tracking}\u0000${segments.length}\u0000${widths}\u0000${line.hyphenated === true}\u0000${font}`;
|
|
18
|
+
let known = painted.get(segments);
|
|
19
|
+
if (known?.key !== key)
|
|
20
|
+
painted.set(segments, known = { key });
|
|
21
|
+
return known;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The segments to paint `line` from, and the order to advance through
|
|
25
|
+
* them in when the line carries one (`VDTLine.order`: a line with
|
|
26
|
+
* right-to-left text, any line of a mirrored page; the pieces of a
|
|
27
|
+
* left-to-right word are joined there too, and the order written for the
|
|
28
|
+
* segments that result). `composed`: a line of the CJK composer, painted
|
|
29
|
+
* as it is. A line set word by word down a vertical page is asked as any
|
|
30
|
+
* other, each text at the advance the vertical painter gives it: a Latin
|
|
31
|
+
* word runs sideways down the column, shaped as on a horizontal line, and
|
|
32
|
+
* a piece of it is as wide as the word grew by it. Chrome 154, Noto Sans
|
|
33
|
+
* JP at 14.58 px under `ja`: the layout holds `BY-` 21.01 and `SA` 17.23
|
|
34
|
+
* px, `BY-SA` being 38.24 px, where `SA` alone is 17.55 px; painted piece
|
|
35
|
+
* by piece `SA` ran 0.32 px into the space after it. `tracking` is the
|
|
36
|
+
* context's `letterSpacing` on entry, px, and on return; `fontOf` gives the font
|
|
37
|
+
* string a segment is painted in. The context's font is left at any
|
|
38
|
+
* value: the painter sets its own before each text.
|
|
39
|
+
*/
|
|
40
|
+
export function paintedSegments(ctx, line, composed, tracking, fontOf) {
|
|
41
|
+
const segments = line.segments;
|
|
42
|
+
const order = segments && !composed && line.order?.length === segments.length ? line.order : undefined;
|
|
43
|
+
if (!segments || segments.length === 0 || composed || typeof ctx.measureText !== 'function')
|
|
44
|
+
return { segments, order };
|
|
45
|
+
const known = knownOf(ctx, line, segments, tracking, fontOf(segments[0]));
|
|
46
|
+
if (known.set)
|
|
47
|
+
return known.set;
|
|
48
|
+
let font = '';
|
|
49
|
+
let spaced = tracking !== 0;
|
|
50
|
+
known.set = lineWordSegmentsInOrder(line, composed, (seg, text) => {
|
|
51
|
+
if (spaced) {
|
|
52
|
+
setLetterSpacing(ctx, 0);
|
|
53
|
+
spaced = false;
|
|
54
|
+
}
|
|
55
|
+
let width = 0;
|
|
56
|
+
inSegmentLanguage(ctx, seg, () => {
|
|
57
|
+
const own = fontOf(seg);
|
|
58
|
+
if (own !== font)
|
|
59
|
+
ctx.font = font = own;
|
|
60
|
+
// Down a vertical page a text advances as its cells and its
|
|
61
|
+
// sideways runs do (`verticalFlowAdvance`).
|
|
62
|
+
width = verticalFlowAdvance(ctx, text, tracking)
|
|
63
|
+
?? contextTextWidth(ctx, text) + (tracking === 0 ? 0 : tracking * graphemeCount(text));
|
|
64
|
+
});
|
|
65
|
+
return width;
|
|
66
|
+
});
|
|
67
|
+
if (tracking !== 0 && !spaced)
|
|
68
|
+
setLetterSpacing(ctx, tracking);
|
|
69
|
+
return known.set;
|
|
70
|
+
}
|
|
71
|
+
/** A character past Latin-1 (see `contextText.ts`). */
|
|
72
|
+
const WIDE_RE = /[^\u0000-\u00FF]/;
|
|
73
|
+
const LETTER_RE = /\p{L}/u;
|
|
74
|
+
/** Whether the browser may set the line's text otherwise as one text than
|
|
75
|
+
* segment by segment: two of its pieces touch (a pair kerned across the
|
|
76
|
+
* cut), the line ends on a hyphen the layout added (measured apart from
|
|
77
|
+
* its word, and a face may kern the two: at 20 px Fira Sans sets `lec-`
|
|
78
|
+
* 0.86 px narrower than `lec` and `-`, Crimson Pro `bo-` 0.29 px wider),
|
|
79
|
+
* or its text holds a character past U+00FF and one of its words is of
|
|
80
|
+
* Latin-1 characters with no letter among them. */
|
|
81
|
+
function mayDifferWhole(line, segments) {
|
|
82
|
+
if (line.hyphenated === true && !line.hardHyphen) {
|
|
83
|
+
const last = segments[segments.length - 1];
|
|
84
|
+
if (last?.kind === 'text' && last.text.length > 1 && last.text.endsWith('-'))
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
const wide = WIDE_RE.test(line.text);
|
|
88
|
+
for (let i = 0; i < segments.length; i++) {
|
|
89
|
+
const seg = segments[i];
|
|
90
|
+
if (seg.kind === 'space')
|
|
91
|
+
continue;
|
|
92
|
+
if (i > 0 && segments[i - 1].kind !== 'space')
|
|
93
|
+
return true;
|
|
94
|
+
if (wide && seg.kind === 'text' && !WIDE_RE.test(seg.text) && !LETTER_RE.test(seg.text))
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Whether a line's text, painted with one `fillText` in the context's
|
|
101
|
+
* font (the line's `font`, set by the caller), is as wide as the layout
|
|
102
|
+
* measured its segments together. `tracking` is the context's
|
|
103
|
+
* `letterSpacing` on entry, px, and on return. A line with no two pieces
|
|
104
|
+
* that touch and no word the browser shapes otherwise inside a longer
|
|
105
|
+
* string is, with nothing asked: its words and its spaces were measured
|
|
106
|
+
* whole. So is any line where the context does not measure.
|
|
107
|
+
*/
|
|
108
|
+
export function paintsAsOneText(ctx, line, tracking, font) {
|
|
109
|
+
const segments = line.segments;
|
|
110
|
+
if (!segments || typeof ctx.measureText !== 'function' || !mayDifferWhole(line, segments))
|
|
111
|
+
return true;
|
|
112
|
+
const known = knownOf(ctx, line, segments, tracking, font);
|
|
113
|
+
if (known.whole === undefined) {
|
|
114
|
+
let measured = 0;
|
|
115
|
+
let widest = 0;
|
|
116
|
+
for (const seg of segments) {
|
|
117
|
+
measured += seg.width;
|
|
118
|
+
if (seg.width > widest)
|
|
119
|
+
widest = seg.width;
|
|
120
|
+
}
|
|
121
|
+
if (tracking !== 0)
|
|
122
|
+
setLetterSpacing(ctx, 0);
|
|
123
|
+
const set = contextTextWidth(ctx, line.text) + (tracking === 0 ? 0 : tracking * graphemeCount(line.text));
|
|
124
|
+
if (tracking !== 0)
|
|
125
|
+
setLetterSpacing(ctx, tracking);
|
|
126
|
+
// What a kerned pair moves is small beside a line: the difference is
|
|
127
|
+
// weighed against the line's widest word, as a word's pieces are.
|
|
128
|
+
known.whole = sameSetWidth(widest + set - measured, widest);
|
|
129
|
+
}
|
|
130
|
+
return known.whole;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=wordPieces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wordPieces.js","sourceRoot":"","sources":["../../src/canvas-backend/wordPieces.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,7 +48,9 @@ export declare function fillSegmentWord(ctx: CanvasRenderingContext2D, seg: VDTL
|
|
|
48
48
|
export declare function inSegmentLanguage(ctx: CanvasRenderingContext2D, seg: VDTLineSegment, paint: () => void): void;
|
|
49
49
|
/** Paint the segments that name a language in it from now on (`on`), or
|
|
50
50
|
* in the page's as up to postext 1.28: the page painter says which for
|
|
51
|
-
* the document it paints (`bodyText.shapingLanguage`).
|
|
51
|
+
* the document it paints (`bodyText.shapingLanguage`). The same
|
|
52
|
+
* documents have the ligatures of their tracked words take the tracking
|
|
53
|
+
* of each letter (`setLetterTracking`, #770). */
|
|
52
54
|
export declare function setSegmentLanguages(on: boolean): void;
|
|
53
55
|
/** Whether a segment that names its language is painted on its own. */
|
|
54
56
|
export declare function paintsSegmentLanguage(seg: VDTLineSegment): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wordRuns.d.ts","sourceRoot":"","sources":["../../src/canvas-backend/wordRuns.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"wordRuns.d.ts","sourceRoot":"","sources":["../../src/canvas-backend/wordRuns.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAS7C,8EAA8E;AAC9E,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAQlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,wBAAwB,EAC7B,GAAG,EAAE,cAAc,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,EACnD,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzD,IAAI,CAEN;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,wBAAwB,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,IAAI,CAa7G;AAMD;;;;kDAIkD;AAClD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAGrD;AAED,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAElE;AA+BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,wBAAwB,EAC7B,GAAG,EAAE,cAAc,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,EACnD,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzD,IAAI,CAsCN"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { shapingTagOf } from '../locale';
|
|
2
2
|
import { joiningScriptIn } from '../measure/joining';
|
|
3
3
|
import { mirroredPaintActive } from './mirrorFrame';
|
|
4
|
-
import { fillTrackedWord } from './trackedText';
|
|
4
|
+
import { fillTrackedWord, setLetterTracking } from './trackedText';
|
|
5
5
|
import { fillScriptWord } from './scriptText';
|
|
6
6
|
import { scriptContextUntracked } from '../measure/script';
|
|
7
7
|
import { restoreContext, saveContext, setLetterSpacing } from './contextState';
|
|
8
|
+
import { contextTextWidth } from './contextText';
|
|
8
9
|
/** How far above and below the baseline a run's clip reaches: past any
|
|
9
10
|
* ascender, stacked vowel sign or descender. */
|
|
10
11
|
const CLIP_REACH = 4096;
|
|
@@ -72,9 +73,12 @@ export function inSegmentLanguage(ctx, seg, paint) {
|
|
|
72
73
|
let segmentLanguages = false;
|
|
73
74
|
/** Paint the segments that name a language in it from now on (`on`), or
|
|
74
75
|
* in the page's as up to postext 1.28: the page painter says which for
|
|
75
|
-
* the document it paints (`bodyText.shapingLanguage`).
|
|
76
|
+
* the document it paints (`bodyText.shapingLanguage`). The same
|
|
77
|
+
* documents have the ligatures of their tracked words take the tracking
|
|
78
|
+
* of each letter (`setLetterTracking`, #770). */
|
|
76
79
|
export function setSegmentLanguages(on) {
|
|
77
80
|
segmentLanguages = on;
|
|
81
|
+
setLetterTracking(on);
|
|
78
82
|
}
|
|
79
83
|
/** Whether a segment that names its language is painted on its own. */
|
|
80
84
|
export function paintsSegmentLanguage(seg) {
|
|
@@ -130,7 +134,7 @@ function fillWord(ctx, seg, x, y, tracking, paint, runStyle) {
|
|
|
130
134
|
export function paintWordRuns(ctx, seg, x, y, paint, runStyle) {
|
|
131
135
|
const text = seg.text;
|
|
132
136
|
const runs = seg.runs;
|
|
133
|
-
const whole = ctx
|
|
137
|
+
const whole = contextTextWidth(ctx, text);
|
|
134
138
|
if (!(whole > 0))
|
|
135
139
|
return;
|
|
136
140
|
const rtl = seg.rtl === true;
|
|
@@ -146,8 +150,8 @@ export function paintWordRuns(ctx, seg, x, y, paint, runStyle) {
|
|
|
146
150
|
from--;
|
|
147
151
|
while (to < text.length && MARK_RE.test(text[to]))
|
|
148
152
|
to++;
|
|
149
|
-
const before = whole - ctx
|
|
150
|
-
const after = whole - ctx
|
|
153
|
+
const before = whole - contextTextWidth(ctx, text.slice(from));
|
|
154
|
+
const after = whole - contextTextWidth(ctx, text.slice(0, to));
|
|
151
155
|
let left = x + Math.max(0, rtl ? after : before);
|
|
152
156
|
let right = x + whole - Math.max(0, rtl ? before : after);
|
|
153
157
|
if (mirroredPaintActive())
|
|
@@ -161,7 +165,7 @@ export function paintWordRuns(ctx, seg, x, y, paint, runStyle) {
|
|
|
161
165
|
ctx.clip();
|
|
162
166
|
ctx.font = font;
|
|
163
167
|
ctx.fillStyle = fill;
|
|
164
|
-
const w = ctx
|
|
168
|
+
const w = contextTextWidth(ctx, text);
|
|
165
169
|
if (w > 0 && Math.abs(w - whole) > 0.01) {
|
|
166
170
|
ctx.translate(x, 0);
|
|
167
171
|
ctx.scale(whole / w, 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wordRuns.js","sourceRoot":"","sources":["../../src/canvas-backend/wordRuns.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"wordRuns.js","sourceRoot":"","sources":["../../src/canvas-backend/wordRuns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fitAsPainted.test.d.ts","sourceRoot":"","sources":["../../../../src/comics/lettering/__tests__/fitAsPainted.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
+
import { clearTextWidthCache, setMeasureLanguage } from '../../../measure/canvas';
|
|
3
|
+
import { prepareText, readLetteringText } from '../text';
|
|
4
|
+
import { shapeText } from '../shape-text';
|
|
5
|
+
import { presetLetteringStyles } from '../presets';
|
|
6
|
+
// #770, round 2: the lines a shaping tries are measured as the layout sets
|
|
7
|
+
// the ones it chooses. In a document shaped in its own language the layout
|
|
8
|
+
// sets a line as wide as its runs are painted, each in its own direction;
|
|
9
|
+
// the shaping measured every line left to right, whole, so a line of an
|
|
10
|
+
// Arabic balloon that ends in a stop or a guillemet was chosen at another
|
|
11
|
+
// width than it is set at.
|
|
12
|
+
const EM = 20;
|
|
13
|
+
const SIZE_RE = /(\d*\.?\d+)px/;
|
|
14
|
+
/**
|
|
15
|
+
* The advance of `text`, in em, in a face that draws its marks by the run
|
|
16
|
+
* they stand in, as Playpen Sans Arabic and Markazi Text do in Arabic: a
|
|
17
|
+
* guillemet is 0.47 em and a stop 0.3 em in a text measured left to right
|
|
18
|
+
* (a run apart from the Arabic word, shaped alone), 0.41 em and 0.2 em in
|
|
19
|
+
* the right-to-left run it is painted in. A space is 0.25 em, any other
|
|
20
|
+
* character half an em.
|
|
21
|
+
*/
|
|
22
|
+
function faceWidth(text, rtl) {
|
|
23
|
+
let em = 0;
|
|
24
|
+
for (const ch of text) {
|
|
25
|
+
if (/[-]/.test(ch))
|
|
26
|
+
continue;
|
|
27
|
+
if (ch === ' ')
|
|
28
|
+
em += 0.25;
|
|
29
|
+
else if (ch === '«' || ch === '»')
|
|
30
|
+
em += rtl ? 0.41 : 0.47;
|
|
31
|
+
else if (ch === '.')
|
|
32
|
+
em += rtl ? 0.2 : 0.3;
|
|
33
|
+
else
|
|
34
|
+
em += 0.5;
|
|
35
|
+
}
|
|
36
|
+
return em;
|
|
37
|
+
}
|
|
38
|
+
class StubCtx {
|
|
39
|
+
font = `${EM}px Test`;
|
|
40
|
+
lang = 'inherit';
|
|
41
|
+
direction = 'ltr';
|
|
42
|
+
measureText(s) {
|
|
43
|
+
const px = Number(SIZE_RE.exec(this.font)?.[1] ?? EM);
|
|
44
|
+
return { width: faceWidth(s, this.direction === 'rtl') * px };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const globals = globalThis;
|
|
48
|
+
globals.OffscreenCanvasRenderingContext2D = StubCtx;
|
|
49
|
+
globals.OffscreenCanvas = class {
|
|
50
|
+
getContext() {
|
|
51
|
+
return new StubCtx();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
clearTextWidthCache();
|
|
55
|
+
afterEach(() => setMeasureLanguage(undefined));
|
|
56
|
+
function shape(text, locale) {
|
|
57
|
+
const style = presetLetteringStyles({ fontSizePx: EM, locale, fontFamily: 'Test' })['speech'];
|
|
58
|
+
const p = prepareText(readLetteringText(text, undefined), style, { locale, vertical: false });
|
|
59
|
+
const shaped = shapeText(p, style, { locale, vertical: false, dpi: 96 });
|
|
60
|
+
return { shaped, lines: shaped.lines.map((l) => p.text.slice(l.start, l.end)) };
|
|
61
|
+
}
|
|
62
|
+
// Two sentences, each closed by a stop; the second inside guillemets.
|
|
63
|
+
const ARABIC = 'هذا هو النص الاول. «وهذا هو النص الثاني.»';
|
|
64
|
+
describe('#770: a balloon line is fitted at the width it is set at', () => {
|
|
65
|
+
it('in a document shaped in its own language, a right-to-left line as it is painted', () => {
|
|
66
|
+
setMeasureLanguage('ar');
|
|
67
|
+
const { shaped, lines } = shape(ARABIC, 'ar');
|
|
68
|
+
const set = shaped.block.lines.filter((l) => l.text.length > 0);
|
|
69
|
+
expect(set).toHaveLength(lines.length);
|
|
70
|
+
// The layout sets each line as one right-to-left run.
|
|
71
|
+
set.forEach((l, i) => expect(l.width).toBeCloseTo(faceWidth(lines[i], true) * EM, 6));
|
|
72
|
+
// And the shaping chose it at that width.
|
|
73
|
+
shaped.lines.forEach((l, i) => expect(l.width).toBeCloseTo(set[i].width, 6));
|
|
74
|
+
// The text holds marks the two directions set at other widths.
|
|
75
|
+
expect(faceWidth(ARABIC, false)).toBeGreaterThan(faceWidth(ARABIC, true) + 0.3);
|
|
76
|
+
});
|
|
77
|
+
it('in a document shaped in its host’s language, left to right and whole, as it was', () => {
|
|
78
|
+
const { shaped, lines } = shape(ARABIC, 'ar');
|
|
79
|
+
const set = shaped.block.lines.filter((l) => l.text.length > 0);
|
|
80
|
+
shaped.lines.forEach((l, i) => {
|
|
81
|
+
expect(l.width).toBeCloseTo(faceWidth(lines[i], false) * EM, 6);
|
|
82
|
+
expect(set[i].width).toBeCloseTo(l.width, 6);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
it('a left-to-right line whole, whatever the document is shaped in', () => {
|
|
86
|
+
const text = 'This is one line. «And this is another.»';
|
|
87
|
+
const host = shape(text, 'en');
|
|
88
|
+
setMeasureLanguage('en');
|
|
89
|
+
const own = shape(text, 'en');
|
|
90
|
+
expect(own.lines).toEqual(host.lines);
|
|
91
|
+
own.shaped.lines.forEach((l, i) => {
|
|
92
|
+
expect(l.width).toBeCloseTo(faceWidth(own.lines[i], false) * EM, 6);
|
|
93
|
+
expect(l.width).toBeCloseTo(host.shaped.lines[i].width, 6);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=fitAsPainted.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fitAsPainted.test.js","sourceRoot":"","sources":["../../../../src/comics/lettering/__tests__/fitAsPainted.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shape-text.d.ts","sourceRoot":"","sources":["../../../src/comics/lettering/shape-text.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAA6B,MAAM,aAAa,CAAC;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAsE,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE/G,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpD,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ;wDACoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;2DACuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;0EAC0E;AAC1E,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,sEAAsE;IACtE,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,qDAAqD;IACrD,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,sEAAsE;IACtE,GAAG,EAAE,IAAI,EAAE,CAAC;IACZ,MAAM,EAAE,IAAI,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;yEACqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB;iBACa;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,8CAA8C;AAC9C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;yEAEyE;AACzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAErE;AAED;;gBAEgB;AAChB,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKxD;
|
|
1
|
+
{"version":3,"file":"shape-text.d.ts","sourceRoot":"","sources":["../../../src/comics/lettering/shape-text.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAA6B,MAAM,aAAa,CAAC;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAsE,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE/G,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpD,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ;wDACoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;2DACuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;0EAC0E;AAC1E,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,sEAAsE;IACtE,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,qDAAqD;IACrD,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,sEAAsE;IACtE,GAAG,EAAE,IAAI,EAAE,CAAC;IACZ,MAAM,EAAE,IAAI,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;yEACqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB;iBACa;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,8CAA8C;AAC9C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;yEAEyE;AACzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAErE;AAED;;gBAEgB;AAChB,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKxD;AA0aD,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,GAAG,OAAO,CAItF;AAeD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY,GAAG,UAAU,CAEhG;AAED,kEAAkE;AAClE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAgC3H;AAwMD,8DAA8D;AAC9D,wBAAgB,KAAK,CAAC,KAAK,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,EAAE,CAgBtF;AAED;4DAC4D;AAC5D,wBAAgB,cAAc,CAAC,KAAK,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,kBAAkB,CAMpG"}
|
|
@@ -19,7 +19,7 @@ import { parseRichDesignText, richDesignSpans, richFontSet, RichMeasurer } from
|
|
|
19
19
|
import { composeCjkDesignParagraph, composesDesignAsCjk } from '../../design/cjkText';
|
|
20
20
|
import { cjkCompositionKey, getCjkComposition, setCjkComposition } from '../../measure/cjkPunctuation';
|
|
21
21
|
import { layoutTextElementAt } from '../../design/layout';
|
|
22
|
-
import { designBaseDirection } from '../../design/bidiText';
|
|
22
|
+
import { designBaseDirection, directedTextWidth, measuresRunsAsPainted } from '../../design/bidiText';
|
|
23
23
|
import { primitiveToBlock } from '../../pipeline/headerFooter';
|
|
24
24
|
import { cjkRegionOf, directionOf, isJapaneseLanguage, languageOf } from '../../locale';
|
|
25
25
|
import { breakPoints, hasMarks, isIsolateControl, markupOf } from './text';
|
|
@@ -101,10 +101,10 @@ function measuringComposition(c) {
|
|
|
101
101
|
* title in two (the comparison of #723). A text whose lines hold no pair
|
|
102
102
|
* is shaped as it was.
|
|
103
103
|
*/
|
|
104
|
-
function composedWidth(text, spans, fonts, pitch, tracking) {
|
|
104
|
+
function composedWidth(text, spans, fonts, pitch, tracking, flowIn) {
|
|
105
105
|
if (text.includes('\n') || !composesDesignAsCjk(text))
|
|
106
106
|
return undefined;
|
|
107
|
-
const measureIn = (t, font) => Math.max(0,
|
|
107
|
+
const measureIn = (t, font) => Math.max(0, flowIn(t, font) + tracking * graphemeCount(t));
|
|
108
108
|
const own = getCjkComposition();
|
|
109
109
|
setCjkComposition(measuringComposition(own));
|
|
110
110
|
try {
|
|
@@ -115,6 +115,27 @@ function composedWidth(text, spans, fonts, pitch, tracking) {
|
|
|
115
115
|
setCjkComposition(own);
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* How the lines a shaping tries are measured, untracked: as the layout
|
|
120
|
+
* that sets the chosen ones measures them (`layoutTextElement`).
|
|
121
|
+
*
|
|
122
|
+
* That is `flowTextWidth`, the text whole and left to right, in a document
|
|
123
|
+
* shaped in its host's language and down a column. In a document shaped
|
|
124
|
+
* in its own language the layout sets a line as wide as its runs are
|
|
125
|
+
* painted, each in its own direction (#770, `measuresRunsAsPainted`), and
|
|
126
|
+
* the shaping measures the same: the line's bidi levels resolved at
|
|
127
|
+
* `base`, the direction the balloon is set at, each run in the direction
|
|
128
|
+
* it is painted in. Measured left to right, the line
|
|
129
|
+
* `منارة بورثكوف، هنا «غانيت».` of an Arabic balloon in Playpen Sans
|
|
130
|
+
* Arabic at 15.625 px is 176.82 px wide, and it is set and painted
|
|
131
|
+
* 177.18 px wide (Chrome 154, in `ar`): its stop and its closing guillemet
|
|
132
|
+
* are a run apart there, and one run with the words when painted. A line
|
|
133
|
+
* with no right-to-left character at a left-to-right base is measured
|
|
134
|
+
* whole either way.
|
|
135
|
+
*/
|
|
136
|
+
function flowMeasure(base) {
|
|
137
|
+
return base !== undefined && measuresRunsAsPainted() ? (t, font) => directedTextWidth(t, font, base) : flowTextWidth;
|
|
138
|
+
}
|
|
118
139
|
/** A measurer of line widths over the prepared text, in the writing mode
|
|
119
140
|
* in force (call inside `withMeasureWritingMode`). Rich text is measured
|
|
120
141
|
* through the design-text measurer of its own markup, so that what is
|
|
@@ -123,16 +144,18 @@ function composedWidth(text, spans, fonts, pitch, tracking) {
|
|
|
123
144
|
* sets with the CJK composer is measured by composing it (#723, see
|
|
124
145
|
* `composedWidth`): the shaping asks for it, the ruby does not (it
|
|
125
146
|
* places a reading along a line, and the start of a line is no line of
|
|
126
|
-
* its own).
|
|
127
|
-
|
|
147
|
+
* its own). `base`: the direction the lines are set at, for a measurer
|
|
148
|
+
* of whole lines ({@link flowMeasure}); the ruby gives none. */
|
|
149
|
+
function measurerFor(p, style, composed = false, base) {
|
|
128
150
|
const tracking = trackingOf(p, style);
|
|
129
151
|
const pitch = style.fontSizePx * style.lineHeight;
|
|
130
152
|
const memo = new Map();
|
|
131
153
|
const key = (a, b) => a * 100003 + b;
|
|
154
|
+
const flowIn = flowMeasure(base);
|
|
132
155
|
if (hasMarks(p)) {
|
|
133
156
|
const rt = parseRichDesignText(wholeMarkup(p), fontSpec(style));
|
|
134
157
|
if (rt.text === p.text) {
|
|
135
|
-
const m = new RichMeasurer(rt, tracking);
|
|
158
|
+
const m = new RichMeasurer(rt, tracking, flowIn === flowTextWidth ? undefined : flowIn);
|
|
136
159
|
const fonts = composed ? richFontSet(fontSpec(style)) : undefined;
|
|
137
160
|
return {
|
|
138
161
|
rich: true,
|
|
@@ -140,7 +163,7 @@ function measurerFor(p, style, composed = false) {
|
|
|
140
163
|
const k = key(a, b);
|
|
141
164
|
let w = memo.get(k);
|
|
142
165
|
if (w === undefined) {
|
|
143
|
-
w = a >= b ? 0 : (fonts && composedWidth(p.text.slice(a, b), () => richDesignSpans(rt, a, b), fonts, pitch, tracking)) ?? m.measure(a, b);
|
|
166
|
+
w = a >= b ? 0 : (fonts && composedWidth(p.text.slice(a, b), () => richDesignSpans(rt, a, b), fonts, pitch, tracking, flowIn)) ?? m.measure(a, b);
|
|
144
167
|
memo.set(k, w);
|
|
145
168
|
}
|
|
146
169
|
return w;
|
|
@@ -158,8 +181,10 @@ function measurerFor(p, style, composed = false) {
|
|
|
158
181
|
if (w === undefined) {
|
|
159
182
|
const row = p.text.slice(a, b);
|
|
160
183
|
const s = row.replace(/[\u2066-\u2069]/g, '');
|
|
161
|
-
|
|
162
|
-
|
|
184
|
+
// The isolates of a line set its runs' levels and print nothing:
|
|
185
|
+
// they stay in the text whose runs are resolved, as in the layout.
|
|
186
|
+
w = a >= b ? 0 : (fonts && composedWidth(row, () => [{ text: row, bold: false, italic: false }], fonts, pitch, tracking, flowIn))
|
|
187
|
+
?? Math.max(0, (flowIn === flowTextWidth ? flowTextWidth(s, font) : flowIn(row, font)) + tracking * graphemeCount(s));
|
|
163
188
|
memo.set(k, w);
|
|
164
189
|
}
|
|
165
190
|
return w;
|
|
@@ -425,10 +450,13 @@ export function shapeTextCandidates(p, style, opts, count) {
|
|
|
425
450
|
breakings.set(p, (byKey = new Map()));
|
|
426
451
|
// The composition is part of the key: a line the CJK composer sets is
|
|
427
452
|
// measured by composing it (#723).
|
|
428
|
-
|
|
453
|
+
// So is the direction the lines are set at, which a document shaped
|
|
454
|
+
// in its own language measures them in (`flowMeasure`).
|
|
455
|
+
const base = vertical ? undefined : baseDirection(p.text, opts.locale);
|
|
456
|
+
const key = [mode, region, level, lang === 'ja', fontString(style), style.letterSpacing ?? 0, style.lineHeight, cjkCompositionKey(getCjkComposition()), base ?? ''].join('|');
|
|
429
457
|
let b = byKey.get(key);
|
|
430
458
|
if (!b)
|
|
431
|
-
byKey.set(key, (b = breakingOf(p, breakPoints(p, level, lang === 'ja'), measurerFor(p, style, true))));
|
|
459
|
+
byKey.set(key, (b = breakingOf(p, breakPoints(p, level, lang === 'ja'), measurerFor(p, style, true, base))));
|
|
432
460
|
// Japanese phrase breaks weigh more than a perfect profile: columns
|
|
433
461
|
// move by whole characters.
|
|
434
462
|
const penaltyWeight = lang === 'ja' ? 1 : 0.5;
|