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,374 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { clearMeasurementCache } from '../measure';
|
|
3
|
+
import { setMeasureLanguage } from '../measure/canvas';
|
|
4
|
+
import { measureRichBlock } from '../measure/rich';
|
|
5
|
+
import { setHyphenationLocale } from '../hyphenate';
|
|
6
|
+
// #770, round 2: the two halves of a word broken at a line end. In a
|
|
7
|
+
// paragraph cut word by word a piece of a word was as wide as the word
|
|
8
|
+
// grew by it, so the rest that opens the next line was the whole word
|
|
9
|
+
// less what stayed above: whatever the face draws across the break (the
|
|
10
|
+
// wide dot of a Catalan `l·l`, a ligature, a kerned pair) stayed in a box
|
|
11
|
+
// nothing paints it in. A document shaped in its own language measures
|
|
12
|
+
// each half as the text painted; one that keeps the host's language keeps
|
|
13
|
+
// the widths it had.
|
|
14
|
+
const SHY = '';
|
|
15
|
+
const DOT = '·';
|
|
16
|
+
const sizeOf = (font) => parseFloat(/(\d*\.?\d+)px/.exec(font)?.[1] ?? '10');
|
|
17
|
+
/**
|
|
18
|
+
* The advance of `text` in a face that draws across its letters, px at
|
|
19
|
+
* 10 px: every letter 5; a space 2.5; a hyphen 3; a full stop 2. `Punt`
|
|
20
|
+
* (as Crimson Pro) sets the middle dot 6 between two `l` in Catalan and
|
|
21
|
+
* 2.5 anywhere else. `Lliga` (as Lora) sets it 2.5 and ligates `l·`,
|
|
22
|
+
* 1.3 narrower. Both: `ff` a ligature 2 narrower, `fi` one 1 narrower,
|
|
23
|
+
* `yo` kerned 1, `o.` kerned 0.5, `-y` kerned 0.4.
|
|
24
|
+
*/
|
|
25
|
+
function faceWidth(text, font, lang) {
|
|
26
|
+
const catalan = lang.toLowerCase().split('-')[0] === 'ca';
|
|
27
|
+
const lliga = font.includes('Lliga');
|
|
28
|
+
const chars = Array.from(text);
|
|
29
|
+
let px = 0;
|
|
30
|
+
chars.forEach((ch, i) => {
|
|
31
|
+
const prev = chars[i - 1];
|
|
32
|
+
const next = chars[i + 1];
|
|
33
|
+
if (ch === ' ' || ch === ' ')
|
|
34
|
+
px += 2.5;
|
|
35
|
+
else if (ch === '-')
|
|
36
|
+
px += 3;
|
|
37
|
+
else if (ch === '.')
|
|
38
|
+
px += 2;
|
|
39
|
+
else if (ch === DOT)
|
|
40
|
+
px += !lliga && catalan && prev === 'l' && next === 'l' ? 6 : 2.5;
|
|
41
|
+
else if (ch.codePointAt(0) >= 0x2E80)
|
|
42
|
+
px += 10;
|
|
43
|
+
else
|
|
44
|
+
px += 5;
|
|
45
|
+
const pair = `${prev ?? ''}${ch}`;
|
|
46
|
+
if (pair === 'ff')
|
|
47
|
+
px -= 2;
|
|
48
|
+
if (pair === 'fi')
|
|
49
|
+
px -= 1;
|
|
50
|
+
if (pair === 'yo')
|
|
51
|
+
px -= 1;
|
|
52
|
+
if (pair === 'o.')
|
|
53
|
+
px -= 0.5;
|
|
54
|
+
if (pair === '-y')
|
|
55
|
+
px -= 0.4;
|
|
56
|
+
if (lliga && pair === `l${DOT}`)
|
|
57
|
+
px -= 1.3;
|
|
58
|
+
});
|
|
59
|
+
return (px * sizeOf(font)) / 10;
|
|
60
|
+
}
|
|
61
|
+
/** The language of the page the layout runs on: what a context left at
|
|
62
|
+
* `inherit` measures in. */
|
|
63
|
+
let host = 'en';
|
|
64
|
+
class MeasureContext {
|
|
65
|
+
font = '10px Punt';
|
|
66
|
+
lang = 'inherit';
|
|
67
|
+
direction = 'ltr';
|
|
68
|
+
measureText(s) {
|
|
69
|
+
return { width: faceWidth(s, this.font, this.lang === 'inherit' ? host : this.lang) };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const globals = globalThis;
|
|
73
|
+
globals.OffscreenCanvasRenderingContext2D = MeasureContext;
|
|
74
|
+
globals.OffscreenCanvas = class {
|
|
75
|
+
getContext() {
|
|
76
|
+
return new MeasureContext();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const PUNT = '10px Punt';
|
|
80
|
+
const LLIGA = '10px Lliga';
|
|
81
|
+
const HYPHEN = 3;
|
|
82
|
+
/** The width of `text` painted alone in `lang`, to a thousandth. */
|
|
83
|
+
const ink = (text, lang, font = PUNT) => faceWidth(text, font, lang);
|
|
84
|
+
const round = (n) => Math.round(n * 1000) / 1000;
|
|
85
|
+
const DOCUMENT_CA = { language: 'ca', locale: 'ca' };
|
|
86
|
+
const HOST_CA = { language: undefined, locale: 'ca' };
|
|
87
|
+
const DOCUMENT_EN = { language: 'en', locale: 'en-us' };
|
|
88
|
+
const HOST_EN = { language: undefined, locale: 'en-us' };
|
|
89
|
+
/** The two breakers: line by line, and Knuth–Plass on a justified text. */
|
|
90
|
+
const GREEDY = { textAlign: 'left', hyphenate: true };
|
|
91
|
+
const OPTIMAL = { textAlign: 'justify', hyphenate: true, optimal: true };
|
|
92
|
+
function lay(text, width, mode, options, font = PUNT) {
|
|
93
|
+
setHyphenationLocale(mode.locale);
|
|
94
|
+
setMeasureLanguage(mode.language);
|
|
95
|
+
return measureRichBlock([{ text, bold: false, italic: false }], font, font, font, font, width, 14, options).lines;
|
|
96
|
+
}
|
|
97
|
+
const words = (line) => (line.segments ?? []).filter((s) => s.kind === 'text');
|
|
98
|
+
/** The text pieces a line carries, each with its width to a thousandth. */
|
|
99
|
+
const pieces = (line) => words(line).map((s) => [s.text, round(s.width)]);
|
|
100
|
+
/** The pieces a line opens with up to its first space, joined: the rest
|
|
101
|
+
* of the word broken at the line before, and its width. */
|
|
102
|
+
function opening(line) {
|
|
103
|
+
let text = '';
|
|
104
|
+
let width = 0;
|
|
105
|
+
for (const s of line.segments ?? []) {
|
|
106
|
+
if (s.kind === 'space')
|
|
107
|
+
break;
|
|
108
|
+
text += s.text;
|
|
109
|
+
width += s.width;
|
|
110
|
+
}
|
|
111
|
+
return [text, round(width)];
|
|
112
|
+
}
|
|
113
|
+
/** The pieces a line ends on, back to its last space, joined. */
|
|
114
|
+
function closing(line) {
|
|
115
|
+
const segs = line.segments ?? [];
|
|
116
|
+
let text = '';
|
|
117
|
+
let width = 0;
|
|
118
|
+
for (let i = segs.length - 1; i >= 0 && segs[i].kind !== 'space'; i--) {
|
|
119
|
+
text = segs[i].text + text;
|
|
120
|
+
width += segs[i].width;
|
|
121
|
+
}
|
|
122
|
+
return [text, round(width)];
|
|
123
|
+
}
|
|
124
|
+
beforeEach(() => {
|
|
125
|
+
host = 'en';
|
|
126
|
+
clearMeasurementCache();
|
|
127
|
+
});
|
|
128
|
+
afterEach(() => {
|
|
129
|
+
setMeasureLanguage(undefined);
|
|
130
|
+
setHyphenationLocale('en-us');
|
|
131
|
+
});
|
|
132
|
+
describe.each([['line by line', GREEDY], ['Knuth–Plass', OPTIMAL]])('a word broken at a line end, %s', (_name, options) => {
|
|
133
|
+
it('the rest of a Catalan word broken inside its l·l is as wide as the text painted', () => {
|
|
134
|
+
// `instal·lar` is 51 px whole in Catalan (the dot 6 px between its two
|
|
135
|
+
// `l`) and `instal·` 32.5 px: the rest was 18.5 px for `lar`, 15 px.
|
|
136
|
+
const text = `aa instal${DOT}lar bb cc`;
|
|
137
|
+
const own = lay(text, 47, DOCUMENT_CA, options);
|
|
138
|
+
expect(own.map((l) => l.text)).toEqual(['aa instal-', 'lar bb cc']);
|
|
139
|
+
expect(opening(own[1])).toEqual(['lar', ink('lar', 'ca')]);
|
|
140
|
+
expect(opening(own[1])[1]).toBe(15);
|
|
141
|
+
// On a Catalan page a document that keeps the host's language is
|
|
142
|
+
// measured in Catalan too, and keeps the rest it had: what the word
|
|
143
|
+
// grew by, the wide dot in it.
|
|
144
|
+
host = 'ca';
|
|
145
|
+
clearMeasurementCache();
|
|
146
|
+
const kept = lay(text, 47, HOST_CA, options);
|
|
147
|
+
expect(kept.map((l) => l.text)).toEqual(['aa instal-', 'lar bb cc']);
|
|
148
|
+
expect(opening(kept[1])).toEqual(['lar', 18.5]);
|
|
149
|
+
});
|
|
150
|
+
it('the breaker counts the rest at the width painted: a line it fits is set', () => {
|
|
151
|
+
// `lar bb cc dd` is 52.5 px as painted and fits a measure of 54; with
|
|
152
|
+
// the rest at 18.5 px it was 56 px, and `dd` went down.
|
|
153
|
+
const text = `aa instal${DOT}lar bb cc dd`;
|
|
154
|
+
host = 'ca';
|
|
155
|
+
clearMeasurementCache();
|
|
156
|
+
expect(lay(text, 54, DOCUMENT_CA, options).map((l) => l.text)).toEqual(['aa instal-', 'lar bb cc dd']);
|
|
157
|
+
expect(lay(text, 54, HOST_CA, options).length).toBeGreaterThan(2);
|
|
158
|
+
});
|
|
159
|
+
it('a ligature undone by the break is not kept in the rest', () => {
|
|
160
|
+
// `office` 27 px (ffi), `of` 10: the rest was 17 px for `fice`, 19 px.
|
|
161
|
+
const text = `aa of${SHY}fice bb`;
|
|
162
|
+
const own = lay(text, 27, DOCUMENT_EN, options);
|
|
163
|
+
expect(own.map((l) => l.text)).toEqual(['aa of-', 'fice', 'bb']);
|
|
164
|
+
expect(opening(own[1])).toEqual(['fice', 19]);
|
|
165
|
+
expect(closing(own[0])).toEqual(['of-', ink('of', 'en') + HYPHEN]);
|
|
166
|
+
const host = lay(text, 27, HOST_EN, options);
|
|
167
|
+
expect(host.map((l) => l.text)).toEqual(['aa of-', 'fice', 'bb']);
|
|
168
|
+
expect(opening(host[1])).toEqual(['fice', 17]);
|
|
169
|
+
expect(closing(host[0])).toEqual(['of-', 13]);
|
|
170
|
+
});
|
|
171
|
+
it('the head of a break inside an l·l is the text before the dot and its hyphen', () => {
|
|
172
|
+
// Lliga ligates `l·`: `col·` is 16.2 px and the dot alone 2.5, so the
|
|
173
|
+
// head was 13.7 px and its hyphen for `col`, 15 px.
|
|
174
|
+
const text = `aa col${DOT}lecció bb`;
|
|
175
|
+
const own = lay(text, 32, DOCUMENT_CA, options, LLIGA);
|
|
176
|
+
expect(own[0].text).toBe('aa col-');
|
|
177
|
+
expect(closing(own[0])).toEqual(['col-', ink('col', 'ca', LLIGA) + HYPHEN]);
|
|
178
|
+
expect(closing(own[0])[1]).toBe(18);
|
|
179
|
+
const host = lay(text, 32, HOST_CA, options, LLIGA);
|
|
180
|
+
expect(host[0].text).toBe('aa col-');
|
|
181
|
+
expect(closing(host[0])[1]).toBe(16.7);
|
|
182
|
+
});
|
|
183
|
+
it('the pieces of the rest are as wide as that rest grows by them', () => {
|
|
184
|
+
// `official` broken after `of`: the next line opens with `ficial`,
|
|
185
|
+
// 29 px, whose `fi` is 9 px (7 px as a piece of `offi`).
|
|
186
|
+
const text = `aa of${SHY}fi${SHY}cial bb`;
|
|
187
|
+
const own = lay(text, 31, DOCUMENT_EN, options);
|
|
188
|
+
expect(own.map((l) => l.text)).toEqual(['aa of-', 'ficial', 'bb']);
|
|
189
|
+
expect(opening(own[1])).toEqual(['ficial', ink('ficial', 'en')]);
|
|
190
|
+
if (options.optimal)
|
|
191
|
+
expect(pieces(own[1])).toEqual([['fi', 9], ['cial', 20]]);
|
|
192
|
+
const host = lay(text, 31, HOST_EN, options);
|
|
193
|
+
expect(opening(host[1])).toEqual(['ficial', 27]);
|
|
194
|
+
if (options.optimal)
|
|
195
|
+
expect(pieces(host[1])).toEqual([['fi', 7], ['cial', 20]]);
|
|
196
|
+
});
|
|
197
|
+
it('a rest that breaks again: the line it leaves is its own text and a hyphen', () => {
|
|
198
|
+
// `efficient` over three lines: `ef-`, `fi-`, `cient`. The middle one
|
|
199
|
+
// was 7 px and a hyphen (what `effi` grew by after `ef`), for `fi`, 9.
|
|
200
|
+
const text = `aa ef${SHY}fi${SHY}cient bb`;
|
|
201
|
+
const own = lay(text, 26, DOCUMENT_EN, options);
|
|
202
|
+
expect(own.map((l) => l.text)).toEqual(['aa ef-', 'fi-', 'cient', 'bb']);
|
|
203
|
+
expect(closing(own[1])).toEqual(['fi-', ink('fi', 'en') + HYPHEN]);
|
|
204
|
+
expect(opening(own[2])).toEqual(['cient', 25]);
|
|
205
|
+
const host = lay(text, 26, HOST_EN, options);
|
|
206
|
+
expect(host.map((l) => l.text)).toEqual(['aa ef-', 'fi-', 'cient', 'bb']);
|
|
207
|
+
expect(closing(host[1])).toEqual(['fi-', 10]);
|
|
208
|
+
});
|
|
209
|
+
it('the rest of an address divided at a joint', () => {
|
|
210
|
+
// `www.oo.oo.oo` cut before its second dot: the pair `o.` is kerned
|
|
211
|
+
// 0.5 px, and the rest was that much narrower than `.oo.oo` alone.
|
|
212
|
+
const text = 'aa www.oo.oo.oo';
|
|
213
|
+
const own = lay(text, 40, DOCUMENT_EN, options);
|
|
214
|
+
expect(own.map((l) => l.text)).toEqual(['aa www.oo', '.oo.oo']);
|
|
215
|
+
expect(opening(own[1])).toEqual(['.oo.oo', ink('.oo.oo', 'en')]);
|
|
216
|
+
expect(opening(own[1])[1]).toBe(23.5);
|
|
217
|
+
const host = lay(text, 40, HOST_EN, options);
|
|
218
|
+
expect(opening(host[1])).toEqual(['.oo.oo', 23]);
|
|
219
|
+
});
|
|
220
|
+
it('a compound that repeats its hyphen: the rest is measured with it', () => {
|
|
221
|
+
const text = 'aa yoyo-yoyo bb';
|
|
222
|
+
const repeat = { ...options, repeatHyphen: true };
|
|
223
|
+
const own = lay(text, 36, DOCUMENT_EN, repeat);
|
|
224
|
+
expect(own.map((l) => l.text)).toEqual(['aa yoyo-', '-yoyo bb']);
|
|
225
|
+
expect(opening(own[1])).toEqual(['-yoyo', round(ink('-yoyo', 'en'))]);
|
|
226
|
+
expect(closing(own[0])).toEqual(['yoyo-', ink('yoyo-', 'en')]);
|
|
227
|
+
});
|
|
228
|
+
it('a word that stays on its line keeps the pieces it had: they add up to the word', () => {
|
|
229
|
+
const text = `An of${SHY}fice and an of${SHY}fi${SHY}cial`;
|
|
230
|
+
for (const mode of [DOCUMENT_EN, HOST_EN]) {
|
|
231
|
+
const lines = lay(text, 400, mode, options);
|
|
232
|
+
expect(lines).toHaveLength(1);
|
|
233
|
+
const all = pieces(lines[0]);
|
|
234
|
+
if (options.optimal)
|
|
235
|
+
expect(all).toEqual([['An', 10], ['of', 10], ['fice', 17], ['and', 15], ['an', 10], ['of', 10], ['fi', 7], ['cial', 20]]);
|
|
236
|
+
else
|
|
237
|
+
expect(all).toEqual([['An', 10], ['office', 27], ['and', 15], ['an', 10], ['official', 37]]);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
describe('a word wider than its line', () => {
|
|
242
|
+
it('is divided, and what is left is measured from the cut on', () => {
|
|
243
|
+
// No syllable here: the word is cut at the last character that fits,
|
|
244
|
+
// between a `y` and the `o` it is kerned to.
|
|
245
|
+
const lines = lay('oyoyoyoyoy', 22.5, DOCUMENT_EN, { textAlign: 'left', hyphenate: false });
|
|
246
|
+
expect(lines.length).toBeGreaterThan(1);
|
|
247
|
+
for (let i = 0; i < lines.length; i++) {
|
|
248
|
+
const [text, width] = closing(lines[i]);
|
|
249
|
+
const body = lines[i].hyphenated && text.endsWith('-') ? text.slice(0, -1) : text;
|
|
250
|
+
expect([text, width]).toEqual([text, round(ink(body, 'en') + (body === text ? 0 : HYPHEN))]);
|
|
251
|
+
}
|
|
252
|
+
expect(lines.map((l) => closing(l))).toEqual([['oyoy-', 22], ['oy-', 13], ['oyoy', 19]]);
|
|
253
|
+
// In the host's language the rest is the word less its head: the pair
|
|
254
|
+
// kerned across each cut stays in it, and the last line is 1 px short
|
|
255
|
+
// of the text it paints for each of the two cuts.
|
|
256
|
+
const host = lay('oyoyoyoyoy', 22.5, HOST_EN, { textAlign: 'left', hyphenate: false });
|
|
257
|
+
expect(host.map((l) => closing(l))).toEqual([['oyoy-', 22], ['oy-', 13], ['oyoy', 17]]);
|
|
258
|
+
});
|
|
259
|
+
it('an address in a Chinese paragraph, cut at a joint by the composer', () => {
|
|
260
|
+
const text = '中文 www.oo.oo.oo 中文';
|
|
261
|
+
const own = lay(text, 52, { language: 'zh-Hans', locale: 'en-us' }, { textAlign: 'left' });
|
|
262
|
+
const at = own.findIndex((l) => l.text.startsWith('.oo'));
|
|
263
|
+
expect(at).toBeGreaterThan(0);
|
|
264
|
+
const rest = words(own[at])[0];
|
|
265
|
+
expect(rest.text.startsWith('.oo')).toBe(true);
|
|
266
|
+
expect(round(rest.width)).toBe(round(ink(rest.text, 'zh-Hans')));
|
|
267
|
+
const host = lay(text, 52, { language: undefined, locale: 'en-us' }, { textAlign: 'left' });
|
|
268
|
+
expect(host.map((l) => l.text)).toEqual(own.map((l) => l.text));
|
|
269
|
+
expect(round(words(host[at])[0].width)).toBe(round(ink(rest.text, 'en') - 0.5));
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
// A word over three lines: its middle line opens with the rest of the
|
|
273
|
+
// first break and ends on a hyphen of its own. Knuth–Plass counts that
|
|
274
|
+
// line while it chooses breaks as the rest's shift, the boxes between the
|
|
275
|
+
// two cuts and the second break's hyphen, and the line set is the text
|
|
276
|
+
// between the cuts measured alone, and its hyphen. The two are one number:
|
|
277
|
+
// both leave out what the word draws from the second cut on, so they part
|
|
278
|
+
// only where the start of the rest changes the glyphs at the second cut.
|
|
279
|
+
// In Chrome 154, over 9 700 such lines in Crimson Pro, Lora, Fira Sans and
|
|
280
|
+
// EB Garamond at measures of 40 to 300 pt (Catalan `l·l`, `ffi`, addresses,
|
|
281
|
+
// repeated hyphens, a soft hyphen after every letter), the breaker's count,
|
|
282
|
+
// the widths written and the text painted were equal to 0.001 px.
|
|
283
|
+
//
|
|
284
|
+
// Each case here sets the middle line in a measure it fills to a
|
|
285
|
+
// thousandth: the breaker takes it when it counts the width set, and may
|
|
286
|
+
// not when the measure is that much narrower.
|
|
287
|
+
describe.each([['line by line', GREEDY], ['Knuth–Plass', OPTIMAL]])('a word over three lines, %s', (_name, options) => {
|
|
288
|
+
/** The lines with no word space: their boxes, summed, to a thousandth. */
|
|
289
|
+
const oneWordLines = (lines) => lines
|
|
290
|
+
.filter((l) => !(l.segments ?? []).some((s) => s.kind === 'space'))
|
|
291
|
+
.map((l) => [l.text, round((l.segments ?? []).reduce((sum, s) => sum + s.width, 0))]);
|
|
292
|
+
/** What a line paints: its text measured alone, the hyphen the layout
|
|
293
|
+
* added measured apart. */
|
|
294
|
+
const painted = (line, lang, font = PUNT) => {
|
|
295
|
+
const added = line.hyphenated === true && !line.hardHyphen && line.text.endsWith('-');
|
|
296
|
+
const body = added ? line.text.slice(0, -1) : line.text;
|
|
297
|
+
return round(ink(body, lang, font) + (added ? HYPHEN : 0));
|
|
298
|
+
};
|
|
299
|
+
it('the middle line of a word whose ligature the first break undoes fills its measure', () => {
|
|
300
|
+
// `of|ficial|ly`: the middle line paints `ficial` (29 px, its `fi`
|
|
301
|
+
// ligature) and a hyphen, 32 px. As what `official` grew by after
|
|
302
|
+
// `of` it was 27 px and a hyphen.
|
|
303
|
+
const text = `aa of${SHY}ficial${SHY}ly bb`;
|
|
304
|
+
const own = lay(text, 32.001, DOCUMENT_EN, options);
|
|
305
|
+
expect(own.map((l) => l.text)).toEqual(['aa of-', 'ficial-', 'ly bb']);
|
|
306
|
+
expect(closing(own[1])).toEqual(['ficial-', 32]);
|
|
307
|
+
expect(pieces(own[1])).toEqual([['ficial-', 32]]);
|
|
308
|
+
// A thousandth narrower it does not fit, and nothing set is past the
|
|
309
|
+
// measure.
|
|
310
|
+
const narrow = lay(text, 31.999, DOCUMENT_EN, options);
|
|
311
|
+
expect(narrow.map((l) => l.text)).not.toContain('ficial-');
|
|
312
|
+
for (const [, width] of oneWordLines(narrow))
|
|
313
|
+
expect(width).toBeLessThanOrEqual(31.999);
|
|
314
|
+
// The host's language keeps the count it had: 30 px, set in 31.999.
|
|
315
|
+
const host = lay(text, 31.999, HOST_EN, options);
|
|
316
|
+
expect(host.map((l) => l.text)).toEqual(['aa of-', 'ficial-', 'ly bb']);
|
|
317
|
+
expect(closing(host[1])).toEqual(['ficial-', 30]);
|
|
318
|
+
});
|
|
319
|
+
it('a middle line that ends inside an l·l: the text before the dot and its hyphen', () => {
|
|
320
|
+
// `ins|tal·|lar` in Catalan: `tal` alone is 15 px, 18 with its hyphen.
|
|
321
|
+
// The word grew by 17.5 px from `ins` to `instal·` (the dot 2.5 px at
|
|
322
|
+
// the end of a text), and the rest after the dot is `lar`, 15 px.
|
|
323
|
+
const text = `instal${DOT}lar`;
|
|
324
|
+
host = 'ca';
|
|
325
|
+
clearMeasurementCache();
|
|
326
|
+
const own = lay(text, 18.001, DOCUMENT_CA, options);
|
|
327
|
+
expect(oneWordLines(own)).toEqual([['ins-', 18], ['tal-', 18], ['lar', 15]]);
|
|
328
|
+
for (const line of own)
|
|
329
|
+
expect(round((line.segments ?? []).reduce((sum, s) => sum + s.width, 0))).toBe(painted(line, 'ca'));
|
|
330
|
+
clearMeasurementCache();
|
|
331
|
+
const narrow = lay(text, 17.999, DOCUMENT_CA, options);
|
|
332
|
+
for (const [, width] of oneWordLines(narrow))
|
|
333
|
+
expect(width).toBeLessThanOrEqual(17.999);
|
|
334
|
+
// A face that ligates `l·` (Lora): the same lines, the same widths.
|
|
335
|
+
clearMeasurementCache();
|
|
336
|
+
const lliga = lay(text, 18.001, DOCUMENT_CA, options, LLIGA);
|
|
337
|
+
expect(oneWordLines(lliga)).toEqual([['ins-', 18], ['tal-', 18], ['lar', 15]]);
|
|
338
|
+
});
|
|
339
|
+
it('a middle line between two hyphens of a compound, the first repeated', () => {
|
|
340
|
+
// `yoyo-yoyo-yoyo`: the middle line paints `-yoyo-`, 23.6 px (the
|
|
341
|
+
// pair `-y` kerned 0.4 px).
|
|
342
|
+
const text = 'yoyo-yoyo-yoyo';
|
|
343
|
+
const repeat = { ...options, repeatHyphen: true };
|
|
344
|
+
const own = lay(text, 23.601, DOCUMENT_EN, repeat);
|
|
345
|
+
expect(oneWordLines(own)).toEqual([['yoyo-', 21], ['-yoyo-', 23.6], ['-yoyo', 20.6]]);
|
|
346
|
+
expect(own.map((l) => round(ink(l.text, 'en')))).toEqual([21, 23.6, 20.6]);
|
|
347
|
+
const narrow = lay(text, 23.599, DOCUMENT_EN, repeat);
|
|
348
|
+
expect(narrow.map((l) => l.text)).not.toContain('-yoyo-');
|
|
349
|
+
for (const [, width] of oneWordLines(narrow))
|
|
350
|
+
expect(width).toBeLessThanOrEqual(23.599);
|
|
351
|
+
});
|
|
352
|
+
it('an address over several lines, each longer than the rest is measured from its break', () => {
|
|
353
|
+
// 80 joints, 243 characters: at these measures a line holds more than
|
|
354
|
+
// the 32 characters measured from the break it opens at, and the rest
|
|
355
|
+
// of it is what the whole address grew by from there on.
|
|
356
|
+
const text = `www${'.oo'.repeat(80)}`;
|
|
357
|
+
let longMiddles = 0;
|
|
358
|
+
for (let measure = 190; measure <= 260; measure += 3.5) {
|
|
359
|
+
clearMeasurementCache();
|
|
360
|
+
const lines = lay(text, measure, DOCUMENT_EN, options);
|
|
361
|
+
expect(lines.length).toBeGreaterThan(2);
|
|
362
|
+
expect(lines.map((l) => l.text).join('')).toBe(text);
|
|
363
|
+
lines.forEach((line, i) => {
|
|
364
|
+
const width = round((line.segments ?? []).reduce((sum, s) => sum + s.width, 0));
|
|
365
|
+
expect([line.text, width]).toEqual([line.text, round(ink(line.text, 'en'))]);
|
|
366
|
+
expect(width).toBeLessThanOrEqual(measure);
|
|
367
|
+
if (i > 0 && i < lines.length - 1 && line.text.length > 32)
|
|
368
|
+
longMiddles++;
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
expect(longMiddles).toBeGreaterThan(20);
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
//# sourceMappingURL=lineEndPieces.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineEndPieces.test.js","sourceRoot":"","sources":["../../src/__tests__/lineEndPieces.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -143,8 +143,8 @@ describe('maths in configurations written before postext 1.5 (EF-75)', () => {
|
|
|
143
143
|
});
|
|
144
144
|
it('writes bundles for today\'s rules, which read back unpinned', async () => {
|
|
145
145
|
const { manifest, bytes } = await createBundle({ name: 'Now', chapters: [{ markdown: CHAPTER }], config: BODY });
|
|
146
|
-
expect(CONFIG_VERSION).toBe(
|
|
147
|
-
expect(manifest.configVersion).toBe(
|
|
146
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
147
|
+
expect(manifest.configVersion).toBe(14);
|
|
148
148
|
const again = await openBundle(bytes);
|
|
149
149
|
expect(again.config.math).toBeUndefined();
|
|
150
150
|
// …and a 1.4 bundle, opened and written again, is read back as it was
|
|
@@ -101,7 +101,7 @@ describe('configurations stored before rules 6 keep the 1.4 box spacing', () =>
|
|
|
101
101
|
// It names the box cut (EF-115), so the box gap is the pin that shows.
|
|
102
102
|
const config = { layout: { layoutType: 'single', boxChildSplitMinLines: 2 } };
|
|
103
103
|
it('pins a configuration whose book embeds a resource in a box, once', () => {
|
|
104
|
-
expect(CONFIG_VERSION).toBe(
|
|
104
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
105
105
|
// Stamped 5 (a 1.5 prerelease): the box gap is the only pin it gets.
|
|
106
106
|
expect(migrateConfig(config, 5, { content: MD }).layout).toEqual({ layoutType: 'single', boxChildSplitMinLines: 2, inlineResourceGapInBoxes: false });
|
|
107
107
|
// Unversioned (1.4): both gap pins.
|
|
@@ -155,7 +155,7 @@ describe('layout.boxChildSplitMinLines', () => {
|
|
|
155
155
|
it('is pinned to 1 for configurations stored before rules 6 whose book holds a box', () => {
|
|
156
156
|
const cfg = { layout: { layoutType: 'single', inlineResourceGap: 'around', inlineResourceGapInBoxes: true } };
|
|
157
157
|
const box = twoLineItems(3);
|
|
158
|
-
expect(CONFIG_VERSION).toBe(
|
|
158
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
159
159
|
// Unversioned (1.4) and stamped 5 (a 1.5 prerelease): pinned.
|
|
160
160
|
expect(migrateConfig(cfg, undefined, { content: box }).layout?.boxChildSplitMinLines).toBe(1);
|
|
161
161
|
expect(migrateConfig(cfg, 5, { content: ['No box here.', box] }).layout?.boxChildSplitMinLines).toBe(1);
|
|
@@ -110,7 +110,7 @@ describe('colonListRoom: \'line\' keeps the postext 1.4 room check (EF-110)', ()
|
|
|
110
110
|
describe('configurations stored before rules 6 keep the 1.4 colon-list room', () => {
|
|
111
111
|
const LIST = 'Look for these signs:\n\n- one\n- two';
|
|
112
112
|
it('pins a configuration older than 6 whose book introduces a list with a colon, once', () => {
|
|
113
|
-
expect(CONFIG_VERSION).toBe(
|
|
113
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
114
114
|
const stored = { bodyText: { fontFamily: 'Georgia' } };
|
|
115
115
|
for (const version of [undefined, 3, 4, 5]) {
|
|
116
116
|
expect(migrateConfig(stored, version, { content: LIST }).bodyText, `${version}`)
|
|
@@ -121,7 +121,7 @@ describe('a break after a compound’s hyphen on both paths (EF-186)', () => {
|
|
|
121
121
|
expect(other).toBeGreaterThan(0);
|
|
122
122
|
});
|
|
123
123
|
it('is pinned off for configurations stored before rules 8 whose text sets a compound', () => {
|
|
124
|
-
expect(CONFIG_VERSION).toBe(
|
|
124
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
125
125
|
const stored = { bodyText: { fontFamily: 'Georgia' } };
|
|
126
126
|
for (const version of [undefined, 3, 6, 7]) {
|
|
127
127
|
expect(migrateConfig(stored, version, { content: EN }).bodyText?.breakAfterHyphens, `${version}`).toBe(false);
|
|
@@ -303,7 +303,7 @@ describe('breakAfterDashes in the configuration', () => {
|
|
|
303
303
|
expect(stripBodyTextDefaults({ breakAfterDashes: false })).toEqual({ breakAfterDashes: false });
|
|
304
304
|
});
|
|
305
305
|
it('is pinned off for configurations stored before rules 7 whose text sets a closed dash', () => {
|
|
306
|
-
expect(CONFIG_VERSION).toBe(
|
|
306
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
307
307
|
const stored = { bodyText: { fontFamily: 'Georgia' } };
|
|
308
308
|
for (const version of [undefined, 3, 5, 6]) {
|
|
309
309
|
expect(migrateConfig(stored, version, { content: ALICE }).bodyText?.breakAfterDashes, `${version}`).toBe(false);
|
|
@@ -103,7 +103,7 @@ describe('a paragraph kept with the heading above it splits by the orphan rule t
|
|
|
103
103
|
}
|
|
104
104
|
// Stored under today's rules, it is read as it is.
|
|
105
105
|
expect(migrateConfig(stored, CONFIG_VERSION, { content: markdown })).toBe(stored);
|
|
106
|
-
expect(CONFIG_VERSION).toBe(
|
|
106
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
107
107
|
});
|
|
108
108
|
it('pins only what the setting changes', () => {
|
|
109
109
|
const plain = { bodyText: { fontFamily: 'Georgia' } };
|
|
@@ -126,7 +126,7 @@ describe('layout.inlineResourceGap and configurations stored before postext 1.5
|
|
|
126
126
|
});
|
|
127
127
|
it('pins a stored configuration whose book embeds a resource, once', () => {
|
|
128
128
|
const config = { layout: { layoutType: 'single' } };
|
|
129
|
-
expect(CONFIG_VERSION).toBe(
|
|
129
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
130
130
|
const pinned = migrateConfig(config, undefined, { content: MD });
|
|
131
131
|
expect(pinned.layout).toEqual({ layoutType: 'single', inlineResourceGap: 'above' });
|
|
132
132
|
// Stamped 4 (a 1.5 prerelease): the gap is the only pin it gets.
|
|
@@ -240,7 +240,7 @@ describe('paragraphStyles[].snapToGrid (EF-184)', () => {
|
|
|
240
240
|
describe('configurations stored before rules 8 keep the 1.4 space under containers', () => {
|
|
241
241
|
const stored = { bodyText: { fontFamily: 'Georgia' }, paragraphStyles: [{ id: 's' }] };
|
|
242
242
|
it('pins \'add\' when the book holds a :::paragraphs container', () => {
|
|
243
|
-
expect(CONFIG_VERSION).toBe(
|
|
243
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
244
244
|
for (const version of [undefined, 3, 5, 6, 7]) {
|
|
245
245
|
expect(migrateConfig(stored, version, { content: GROUP_THEN_HEADING }).bodyText?.paragraphContainerSpacing, `${version}`).toBe('add');
|
|
246
246
|
}
|
|
@@ -168,7 +168,7 @@ describe('optimalRagged in the configuration', () => {
|
|
|
168
168
|
expect(stripBodyTextDefaults({ optimalRagged: false })).toEqual({ optimalRagged: false });
|
|
169
169
|
});
|
|
170
170
|
it('is pinned off for configurations stored before rules 7 that set running text ragged', () => {
|
|
171
|
-
expect(CONFIG_VERSION).toBe(
|
|
171
|
+
expect(CONFIG_VERSION).toBe(14);
|
|
172
172
|
const ragged = { bodyText: { textAlign: 'left' } };
|
|
173
173
|
for (const version of [undefined, 3, 5, 6]) {
|
|
174
174
|
expect(migrateConfig(ragged, version, { content: 'Text.' }).bodyText, `${version}`).toEqual({ textAlign: 'left', optimalRagged: false, scriptContext: false, shapingLanguage: 'host' });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plainGeminateHead.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/plainGeminateHead.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { clearMeasurementCache, measureBlock } from '../measure';
|
|
3
|
+
import { setMeasureLanguage } from '../measure/canvas';
|
|
4
|
+
import { setHyphenationLocale } from '../hyphenate';
|
|
5
|
+
// #770: the head of a break inside a Catalan `l·l`, in a plain paragraph.
|
|
6
|
+
// The line ends on the piece `col·` and prints a hyphen in the dot's
|
|
7
|
+
// place, so the dot's width is given back. The dot set alone was taken
|
|
8
|
+
// for it; a face that sets the dot after an `l` otherwise than alone
|
|
9
|
+
// (Castoro's Catalan form, 0.129 em there and 0.297 em alone; Lora's
|
|
10
|
+
// `l·` ligature) left the head off the text painted: `til-` 22.02 px for
|
|
11
|
+
// 25.28 at 19.4 px in Castoro.
|
|
12
|
+
const DOT = '·';
|
|
13
|
+
/** px at 10 px: every letter 5, a space 2.5, a hyphen 3, the dot 2.5; the
|
|
14
|
+
* face ligates `l·`, 1.3 narrower (as Lora). */
|
|
15
|
+
function faceWidth(text) {
|
|
16
|
+
const chars = Array.from(text);
|
|
17
|
+
let px = 0;
|
|
18
|
+
chars.forEach((ch, i) => {
|
|
19
|
+
if (ch === ' ')
|
|
20
|
+
px += 2.5;
|
|
21
|
+
else if (ch === '-')
|
|
22
|
+
px += 3;
|
|
23
|
+
else if (ch === DOT)
|
|
24
|
+
px += 2.5;
|
|
25
|
+
else
|
|
26
|
+
px += 5;
|
|
27
|
+
if (`${chars[i - 1] ?? ''}${ch}` === `l${DOT}`)
|
|
28
|
+
px -= 1.3;
|
|
29
|
+
});
|
|
30
|
+
return px;
|
|
31
|
+
}
|
|
32
|
+
class MeasureContext {
|
|
33
|
+
font = '10px Lliga';
|
|
34
|
+
lang = 'inherit';
|
|
35
|
+
direction = 'ltr';
|
|
36
|
+
measureText(s) {
|
|
37
|
+
return { width: faceWidth(s) };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const globals = globalThis;
|
|
41
|
+
const saved = { canvas: globals.OffscreenCanvas, context: globals.OffscreenCanvasRenderingContext2D };
|
|
42
|
+
const FONT = '10px Lliga';
|
|
43
|
+
const TEXT = `aa col${DOT}lecció bb`;
|
|
44
|
+
const GREEDY = { textAlign: 'left', hyphenate: true };
|
|
45
|
+
const OPTIMAL = { textAlign: 'justify', hyphenate: true, optimal: true };
|
|
46
|
+
function lay(language, options) {
|
|
47
|
+
setHyphenationLocale('ca');
|
|
48
|
+
setMeasureLanguage(language);
|
|
49
|
+
return measureBlock(TEXT, FONT, 32, 14, options).lines;
|
|
50
|
+
}
|
|
51
|
+
/** The width of the pieces a line ends on, back to its last space. */
|
|
52
|
+
function closing(line) {
|
|
53
|
+
let width = 0;
|
|
54
|
+
for (const s of [...(line.segments ?? [])].reverse()) {
|
|
55
|
+
if (s.kind === 'space')
|
|
56
|
+
break;
|
|
57
|
+
width += s.width;
|
|
58
|
+
}
|
|
59
|
+
return Math.round(width * 1000) / 1000;
|
|
60
|
+
}
|
|
61
|
+
describe('the head of a break inside an l·l in a plain paragraph (#770)', () => {
|
|
62
|
+
beforeEach(() => {
|
|
63
|
+
globals.OffscreenCanvasRenderingContext2D = MeasureContext;
|
|
64
|
+
globals.OffscreenCanvas = class {
|
|
65
|
+
getContext() {
|
|
66
|
+
return new MeasureContext();
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
clearMeasurementCache();
|
|
70
|
+
});
|
|
71
|
+
afterEach(() => {
|
|
72
|
+
setMeasureLanguage(undefined);
|
|
73
|
+
clearMeasurementCache();
|
|
74
|
+
globals.OffscreenCanvas = saved.canvas;
|
|
75
|
+
globals.OffscreenCanvasRenderingContext2D = saved.context;
|
|
76
|
+
});
|
|
77
|
+
for (const [name, options] of [['line by line', GREEDY], ['Knuth–Plass', OPTIMAL]]) {
|
|
78
|
+
it(`${name}: a document shaped in its own language measures the letters before the dot and the hyphen`, () => {
|
|
79
|
+
const lines = lay('ca', options);
|
|
80
|
+
expect(lines[0].text).toBe('aa col-');
|
|
81
|
+
// `col` 15 px and the hyphen 3: the text painted.
|
|
82
|
+
expect(closing(lines[0])).toBe(18);
|
|
83
|
+
});
|
|
84
|
+
it(`${name}: one shaped in the host's language keeps the width it had`, () => {
|
|
85
|
+
const lines = lay(undefined, options);
|
|
86
|
+
expect(lines[0].text).toBe('aa col-');
|
|
87
|
+
// `col·` 16.2 px, less the dot alone, 2.5, and the hyphen.
|
|
88
|
+
expect(closing(lines[0])).toBe(16.7);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=plainGeminateHead.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plainGeminateHead.test.js","sourceRoot":"","sources":["../../src/__tests__/plainGeminateHead.test.ts"],"names":[],"mappings":"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"}
|