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
package/dist/measure/rich.js
CHANGED
|
@@ -13,7 +13,7 @@ import { hasOverfullLine } from './plain';
|
|
|
13
13
|
import { justifiedSpaceRatios } from './spaceRatios';
|
|
14
14
|
import { quoteFamily } from './font';
|
|
15
15
|
import { trimChipLineEdges } from './chipEdges';
|
|
16
|
-
import { directChipRuns } from '../design/bidiText';
|
|
16
|
+
import { directChipRuns, measuresRunsAsPainted, paintedRunWidth } from '../design/bidiText';
|
|
17
17
|
import { cjkJoinBreaks, hasCJK } from './cjk';
|
|
18
18
|
import { composeCjkParagraph, cjkWordBreaks, composesAsCjk, composesDashRow, spanMarks } from './cjkCompose';
|
|
19
19
|
import { getCjkComposition } from './cjkPunctuation';
|
|
@@ -150,9 +150,11 @@ function pieceScriptFields(token, from, to) {
|
|
|
150
150
|
/** The width of a word of a joining script (Arabic…), always painted
|
|
151
151
|
* right to left: measured so too in a face that draws its punctuation by
|
|
152
152
|
* script (#725, `rtlTextWidth`), so the bracket or the stop at its edge
|
|
153
|
-
* takes the forms it is painted in
|
|
153
|
+
* takes the forms it is painted in, and in every face in a document
|
|
154
|
+
* shaped in its own language (#770, see `rtlTextWidth`); as any text
|
|
155
|
+
* otherwise. */
|
|
154
156
|
function rtlWordWidth(text, font) {
|
|
155
|
-
return getMeasureScriptContext().enabled && !measuringVertically() && faceReadsScript(font) ? rtlTextWidth(text, font) : textWidth(text, font, false);
|
|
157
|
+
return getMeasureScriptContext().enabled && !measuringVertically() && (faceReadsScript(font) || getMeasureLanguage() !== undefined) ? rtlTextWidth(text, font) : textWidth(text, font, false);
|
|
156
158
|
}
|
|
157
159
|
/** How a token's text is measured: in its script when it is a word with
|
|
158
160
|
* no letter given one (#725), else as any text (`textWidth`). */
|
|
@@ -175,6 +177,103 @@ function tokenTextWidth(token, font) {
|
|
|
175
177
|
return (text) => (isLetterless(text) ? scriptTextWidth(text, font, word, false) : textWidth(text, font, token.smallCaps));
|
|
176
178
|
return (text) => textWidth(text, font, token.smallCaps);
|
|
177
179
|
}
|
|
180
|
+
/** How many characters of the rest of a word are measured with what
|
|
181
|
+
* follows the break (see {@link ownRest}): past any kerned pair,
|
|
182
|
+
* ligature or contextual form a face draws across one cut. */
|
|
183
|
+
const REST_WINDOW = 32;
|
|
184
|
+
/**
|
|
185
|
+
* The rest of a word from the break at `from`, measured as the text a
|
|
186
|
+
* line opens with (#770): the function gives the width of the word's
|
|
187
|
+
* characters `[from, to)` set as a text of their own, `lead` (the hyphen
|
|
188
|
+
* a compound repeats at the line's start) before them, with the tracking
|
|
189
|
+
* the word was measured with.
|
|
190
|
+
*
|
|
191
|
+
* Up to postext 1.29 that rest was the whole word less what stayed on the
|
|
192
|
+
* line above, and its pieces what the whole word grew by. The browser
|
|
193
|
+
* measured those strings whole, so whatever the face draws across the
|
|
194
|
+
* break stayed in the rest's box, and nothing paints it there. Crimson
|
|
195
|
+
* Pro sets the dot of a Catalan `l·l` 0.586 em wide: `instal·lar` broken
|
|
196
|
+
* as `instal-` | `lar` left `lar` a box of 28.54 px at 20 px for a text
|
|
197
|
+
* painted 21.62 px wide. EB Garamond's `of-` | `fice` left 24.7 px for
|
|
198
|
+
* 25.9 (the `ffi` ligature undone by the break), and Fira Sans's `lar`
|
|
199
|
+
* 20.74 px for 24.36 (its `l·` ligature). Measured in Chrome 154.
|
|
200
|
+
*
|
|
201
|
+
* The pieces after the break are measured as that text grows, so a rest
|
|
202
|
+
* that breaks again is right too, and the pieces a line carries add up to
|
|
203
|
+
* the text painted. Only the first {@link REST_WINDOW} characters are
|
|
204
|
+
* measured from the break; a piece that ends past them is what the word
|
|
205
|
+
* grew by from there on, which no break before it changes. A word many
|
|
206
|
+
* lines long then costs what a line of it does.
|
|
207
|
+
*
|
|
208
|
+
* `token` is the word as it stands (itself the rest of an earlier break,
|
|
209
|
+
* or the whole word); a document that keeps the host's language never
|
|
210
|
+
* asks.
|
|
211
|
+
*/
|
|
212
|
+
function ownRest(token, from, font, lead = '') {
|
|
213
|
+
const text = token.text;
|
|
214
|
+
const spacing = token.ownPieces ?? 0;
|
|
215
|
+
const tracked = (width, piece) => (spacing === 0 ? width : width + spacing * graphemeCount(piece));
|
|
216
|
+
const whole = tokenTextWidth(token, font);
|
|
217
|
+
const before = (idx) => (idx >= text.length ? token.width : tracked(whole(text.slice(0, idx)), text.slice(0, idx)));
|
|
218
|
+
const rest = tokenTextWidth({ ...scriptOf(token), ...pieceScriptFields(token, from, text.length) }, font);
|
|
219
|
+
const own = (piece) => tracked(rest(piece), piece);
|
|
220
|
+
let end = Math.min(text.length, from + REST_WINDOW);
|
|
221
|
+
// Not between the two halves of a character outside the BMP.
|
|
222
|
+
if (end < text.length && (text.charCodeAt(end) & 0xFC00) === 0xDC00)
|
|
223
|
+
end++;
|
|
224
|
+
let window;
|
|
225
|
+
let anchor;
|
|
226
|
+
return (to) => {
|
|
227
|
+
if (to <= end)
|
|
228
|
+
return own(lead + text.slice(from, to));
|
|
229
|
+
window ??= own(lead + text.slice(from, end));
|
|
230
|
+
anchor ??= before(end);
|
|
231
|
+
return window + before(to) - anchor;
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/** The break points of `token` after `at`, for its rest measured as a
|
|
235
|
+
* text of its own (`width`, see {@link ownRest}): each as far into that
|
|
236
|
+
* text as it is, the dot of an `l·l` measured there too. */
|
|
237
|
+
function ownRestBreaks(token, at, width, shift = 0) {
|
|
238
|
+
return (token.breakPoints ?? [])
|
|
239
|
+
.filter((b) => b.charIndex > at)
|
|
240
|
+
.map((b) => {
|
|
241
|
+
const { restShift: _shift, ...rest } = b;
|
|
242
|
+
void _shift;
|
|
243
|
+
const widthBefore = width(b.charIndex);
|
|
244
|
+
return {
|
|
245
|
+
...rest,
|
|
246
|
+
charIndex: b.charIndex - at + shift,
|
|
247
|
+
widthBefore,
|
|
248
|
+
...(b.replacesWidth !== undefined ? { replacesWidth: widthBefore - width(b.charIndex - 1) } : {}),
|
|
249
|
+
};
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Knuth–Plass in a document shaped in its own language (#770): give each
|
|
254
|
+
* break point of the words measured so ({@link RichToken.ownPieces}) what
|
|
255
|
+
* the rest of its word is wider, opening the next line as a text of its
|
|
256
|
+
* own, than the pieces after the break add up to
|
|
257
|
+
* (`RichBreakPoint.restShift`). `lead`: the hyphen a compound repeats at
|
|
258
|
+
* that line's start (`repeatHyphen`) is part of the text measured, and its
|
|
259
|
+
* own width, which the breaker counts apart, is taken off.
|
|
260
|
+
* One measure a break point, two for a rest longer than
|
|
261
|
+
* {@link REST_WINDOW} characters.
|
|
262
|
+
*/
|
|
263
|
+
function markRestShifts(tokens, fontOf, repeatHyphen) {
|
|
264
|
+
for (const token of tokens) {
|
|
265
|
+
if (token.ownPieces === undefined || !token.breakPoints)
|
|
266
|
+
continue;
|
|
267
|
+
const font = fontOf(token);
|
|
268
|
+
for (const bp of token.breakPoints) {
|
|
269
|
+
if (bp.greedyOnly)
|
|
270
|
+
continue;
|
|
271
|
+
const repeated = repeatHyphen && bp.bare === true && !token.bareBreaks;
|
|
272
|
+
const own = ownRest(token, bp.charIndex, font, repeated ? '-' : '')(token.text.length);
|
|
273
|
+
bp.restShift = own - (repeated ? token.hyphenWidth ?? 0 : 0) - (token.width - bp.widthBefore);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
178
277
|
/** Small capitals are synthesised, the same way on every backend: a
|
|
179
278
|
* lowercase letter is set as its capital at this fraction of the text
|
|
180
279
|
* size, while capitals, digits and punctuation keep the full size — the
|
|
@@ -360,8 +459,12 @@ export function chipToken(span, normalFont, boldFont, italicFont, boldItalicFont
|
|
|
360
459
|
}
|
|
361
460
|
// Right-to-left runs cut where the direction changes, and their order
|
|
362
461
|
// (`VDTChip.order`).
|
|
363
|
-
|
|
364
|
-
|
|
462
|
+
// In a document shaped in its own language each is as wide as it is
|
|
463
|
+
// painted, in its own direction, and the chip as wide as its runs (#770,
|
|
464
|
+
// `measuresRunsAsPainted`).
|
|
465
|
+
const asPainted = measuresRunsAsPainted();
|
|
466
|
+
const directed = directChipRuns(runs, (t, f, rtl) => (asPainted ? paintedRunWidth(t, f, rtl) : measureTextWidth(t, f)) + wordLetterSpacing(t, letterSpacingPx) * graphemeCount(t), asPainted);
|
|
467
|
+
const textWidth = (asPainted ? directed.runs : runs).reduce((sum, r) => sum + r.width, 0);
|
|
365
468
|
const paddingX = box?.paddingXPx ?? 0;
|
|
366
469
|
const paddingY = box?.paddingYPx ?? 0;
|
|
367
470
|
// A style may pad the top and the bottom apart (EF-172).
|
|
@@ -542,7 +645,14 @@ function syllabify(word, hyphenate, byDictionary = false) {
|
|
|
542
645
|
function wordBreakPoints(clean, soft, font, letterSpacingPx, smallCaps, dashBreaks = false, touching, cjk,
|
|
543
646
|
/** How the word's pieces are measured when not as any text: in the
|
|
544
647
|
* script of a word with no letter (#725). */
|
|
545
|
-
measure
|
|
648
|
+
measure,
|
|
649
|
+
/** A document shaped in its own language (#770): the head of a break
|
|
650
|
+
* inside an `l·l` is as wide as the text painted, `col` and its hyphen.
|
|
651
|
+
* Taking the dot's own width off `col·` is short of it where the face
|
|
652
|
+
* draws the two together: Lora ligates `l·`, and left `col-` 1.32 px
|
|
653
|
+
* narrower than painted at 20 px (36.14 px for 37.46); Fira Sans,
|
|
654
|
+
* 0.2 px. */
|
|
655
|
+
ownHeads = false) {
|
|
546
656
|
const widthBefore = cjk
|
|
547
657
|
? cjk.widthBefore
|
|
548
658
|
: (idx) => (measure ? measure(clean.slice(0, idx)) : textWidth(clean.slice(0, idx), font, smallCaps)) + (letterSpacingPx === 0 ? 0 : letterSpacingPx * graphemeCount(clean.slice(0, idx)));
|
|
@@ -573,7 +683,7 @@ measure) {
|
|
|
573
683
|
}
|
|
574
684
|
for (const s of soft) {
|
|
575
685
|
const geminate = endsInsideGeminate(clean.slice(0, s.index))
|
|
576
|
-
? { replacesWidth: textWidth(GEMINATE_DOT, font, smallCaps) + letterSpacingPx }
|
|
686
|
+
? { replacesWidth: ownHeads ? widthBefore(s.index) - widthBefore(s.index - 1) : textWidth(GEMINATE_DOT, font, smallCaps) + letterSpacingPx }
|
|
577
687
|
: {};
|
|
578
688
|
add(s.author ? { charIndex: s.index, author: true, ...geminate } : { charIndex: s.index, ...geminate });
|
|
579
689
|
}
|
|
@@ -613,6 +723,11 @@ export function emergencySplit(token, font, letterSpacingPx, lineMaxWidth, sylla
|
|
|
613
723
|
const measure = tokenTextWidth(token, font);
|
|
614
724
|
const widthBefore = (idx) => measure(text.slice(0, idx)) + (spacing === 0 ? 0 : spacing * graphemeCount(text.slice(0, idx)));
|
|
615
725
|
const flags = { bold: token.bold, italic: token.italic, captionLabel: token.captionLabel, ...scriptOf(token) };
|
|
726
|
+
// In a document shaped in its own language the rest is measured as the
|
|
727
|
+
// text that opens the next line (#770, `ownRest`), with the tracking
|
|
728
|
+
// this division measures the word with.
|
|
729
|
+
const own = getMeasureLanguage() !== undefined && !measuringVertically() && !hasCJK(text) ? { ...token, ownPieces: spacing } : undefined;
|
|
730
|
+
const restFrom = (at) => (own ? tailAfter(own, at, 0, font) : tailAfter(token, at, widthBefore(at)));
|
|
616
731
|
// A group glued by no-break spaces too wide for any line: the space is
|
|
617
732
|
// the least bad place to part it (EF-66). The line ends before it and the
|
|
618
733
|
// next one opens after it.
|
|
@@ -624,7 +739,7 @@ export function emergencySplit(token, font, letterSpacingPx, lineMaxWidth, sylla
|
|
|
624
739
|
continue;
|
|
625
740
|
return {
|
|
626
741
|
head: { ...flags, ...pieceScriptFields(token, 0, idx), text: text.slice(0, idx), kind: 'text', width: headWidth },
|
|
627
|
-
tail: { ...
|
|
742
|
+
tail: { ...restFrom(idx + 1), ...flags, ...pieceScriptFields(token, idx + 1, text.length) },
|
|
628
743
|
};
|
|
629
744
|
}
|
|
630
745
|
// No hyphen where the cut falls next to an ideograph, or right after a
|
|
@@ -698,27 +813,34 @@ export function emergencySplit(token, font, letterSpacingPx, lineMaxWidth, sylla
|
|
|
698
813
|
head: geminate
|
|
699
814
|
? { ...flags, text: withLineEndHyphen(text.slice(0, at)), kind: 'text', width: widthBefore(at - 1) + markW(at) }
|
|
700
815
|
: { ...flags, ...pieceScriptFields(token, 0, at), text: text.slice(0, at) + mark, kind: 'text', width: widthBefore(at) + markW(at) },
|
|
701
|
-
tail: { ...
|
|
816
|
+
tail: { ...restFrom(at), ...flags, ...pieceScriptFields(token, at, text.length) },
|
|
702
817
|
...(afterHyphen(at) ? { hard: true } : {}),
|
|
703
818
|
};
|
|
704
819
|
}
|
|
705
820
|
/** What is left of `token` after a cut at `at` (`cutWidth` px in): its text
|
|
706
821
|
* and width from there, the break points after the cut moved with it, and
|
|
707
822
|
* what they need (the hyphen's width; a web address's joints stay bare),
|
|
708
|
-
* so the next line breaks the rest where it could break the whole.
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
823
|
+
* so the next line breaks the rest where it could break the whole.
|
|
824
|
+
* With `font`, for a word whose halves are measured as the texts painted
|
|
825
|
+
* (`RichToken.ownPieces`, #770): the rest and its break points are
|
|
826
|
+
* measured from the cut on ({@link ownRest}), and `cutWidth` is not read. */
|
|
827
|
+
function tailAfter(token, at, cutWidth, font) {
|
|
828
|
+
const own = font !== undefined && token.ownPieces !== undefined ? ownRest(token, at, font) : undefined;
|
|
829
|
+
const residual = own
|
|
830
|
+
? ownRestBreaks(token, at, own)
|
|
831
|
+
: (token.breakPoints ?? [])
|
|
832
|
+
.filter((b) => b.charIndex > at)
|
|
833
|
+
.map((b) => ({ ...b, charIndex: b.charIndex - at, widthBefore: b.widthBefore - cutWidth }));
|
|
713
834
|
return {
|
|
714
835
|
text: token.text.slice(at),
|
|
715
836
|
bold: token.bold,
|
|
716
837
|
italic: token.italic,
|
|
717
838
|
kind: 'text',
|
|
718
|
-
width: token.width - cutWidth,
|
|
839
|
+
width: own ? own(token.text.length) : token.width - cutWidth,
|
|
719
840
|
...(residual.length > 0 ? { breakPoints: residual, hyphenWidth: token.hyphenWidth } : {}),
|
|
720
841
|
...(token.bareBreaks ? { bareBreaks: true } : {}),
|
|
721
842
|
...(token.dashJoin ? { dashJoin: true } : {}),
|
|
843
|
+
...(own ? { ownPieces: token.ownPieces } : {}),
|
|
722
844
|
};
|
|
723
845
|
}
|
|
724
846
|
/** For each character of the spans' joined text, whether it sits in a
|
|
@@ -1100,6 +1222,9 @@ keepAll = false) {
|
|
|
1100
1222
|
// in a face that draws its punctuation by script; the paragraph's text
|
|
1101
1223
|
// and isolates are read when the first such word turns up.
|
|
1102
1224
|
const scriptState = getMeasureScriptContext();
|
|
1225
|
+
// A document shaped in its own language measures the two halves of a
|
|
1226
|
+
// word broken at a line end as the texts painted (#770).
|
|
1227
|
+
const ownPieces = getMeasureLanguage() !== undefined && !measuringVertically();
|
|
1103
1228
|
let paragraphText;
|
|
1104
1229
|
let isolates;
|
|
1105
1230
|
// `script` undefined: a word with letters. Right to left, it is measured
|
|
@@ -1109,9 +1234,14 @@ keepAll = false) {
|
|
|
1109
1234
|
const contextOf = !scriptState.enabled || measuringVertically()
|
|
1110
1235
|
? undefined
|
|
1111
1236
|
: (word, at, length, font) => {
|
|
1112
|
-
if (!faceReadsScript(font) || hasCJK(word))
|
|
1113
|
-
return undefined;
|
|
1114
1237
|
const rtl = bidi !== undefined && (bidi.levels[at] & 1) === 1;
|
|
1238
|
+
// A face whose marks are the same in every script: no word of it
|
|
1239
|
+
// is given one, and a right-to-left word is still measured as it
|
|
1240
|
+
// is painted in a document shaped in its own language (#770).
|
|
1241
|
+
if (!faceReadsScript(font))
|
|
1242
|
+
return rtl && getMeasureLanguage() !== undefined && !hasCJK(word) ? { script: undefined, rtl } : undefined;
|
|
1243
|
+
if (hasCJK(word))
|
|
1244
|
+
return undefined;
|
|
1115
1245
|
if (!isLetterless(word)) {
|
|
1116
1246
|
if (rtl)
|
|
1117
1247
|
return { script: undefined, rtl };
|
|
@@ -1243,6 +1373,9 @@ keepAll = false) {
|
|
|
1243
1373
|
kind: 'text',
|
|
1244
1374
|
width: (inScript.whole ? inScript.whole(clean) : textWidth(clean, font, sc)) + (inScript.untracked ? 0 : track(clean)),
|
|
1245
1375
|
...(breakPoints.length > 0 ? { breakPoints, hyphenWidth: 0, bareBreaks: true } : {}),
|
|
1376
|
+
// The rest of an address divided at a joint is measured as the
|
|
1377
|
+
// text that opens the next line (#770).
|
|
1378
|
+
...(ownPieces && breakPoints.length > 0 ? { ownPieces: spacing } : {}),
|
|
1246
1379
|
});
|
|
1247
1380
|
continue;
|
|
1248
1381
|
}
|
|
@@ -1268,7 +1401,7 @@ keepAll = false) {
|
|
|
1268
1401
|
const wordSpacing = isSpace ? letterSpacingPx : untracked ? 0 : wordLetterSpacing(clean, letterSpacingPx);
|
|
1269
1402
|
const inScript = measured.whole;
|
|
1270
1403
|
const contextFields = measured.fields;
|
|
1271
|
-
const breakPoints = isSpace ? [] : wordBreakPoints(clean, soft, font, wordSpacing, sc, dashBreaks, touching, cjk, measured.upTo);
|
|
1404
|
+
const breakPoints = isSpace ? [] : wordBreakPoints(clean, soft, font, wordSpacing, sc, dashBreaks, touching, cjk, measured.upTo, ownPieces && !cjk);
|
|
1272
1405
|
if (breakPoints.length > 0) {
|
|
1273
1406
|
tokens.push({
|
|
1274
1407
|
text: clean,
|
|
@@ -1282,6 +1415,9 @@ keepAll = false) {
|
|
|
1282
1415
|
width: cjk ? cjk.width : (inScript ? inScript(clean) : textWidth(clean, font, sc)) + (untracked ? 0 : track(clean)),
|
|
1283
1416
|
breakPoints,
|
|
1284
1417
|
hyphenWidth: measureTextWidth('-', font) + letterSpacingPx,
|
|
1418
|
+
// A word that holds CJK characters is measured unit by unit:
|
|
1419
|
+
// its rest is already the text that opens the next line.
|
|
1420
|
+
...(ownPieces && !cjk ? { ownPieces: wordSpacing } : {}),
|
|
1285
1421
|
});
|
|
1286
1422
|
}
|
|
1287
1423
|
else {
|
|
@@ -1503,11 +1639,15 @@ function isDivisible(token) {
|
|
|
1503
1639
|
/** Cut a word at one of its break points: the head ends the line (with
|
|
1504
1640
|
* `mark`, `markWidth` px wide, appended — or in place of the middle dot of
|
|
1505
1641
|
* an `l·l`), the tail keeps the break points after the cut. */
|
|
1506
|
-
function splitToken(token, bp, mark, markWidth) {
|
|
1642
|
+
function splitToken(token, bp, mark, markWidth, font) {
|
|
1507
1643
|
const flags = { bold: token.bold, italic: token.italic, captionLabel: token.captionLabel, ...scriptOf(token) };
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1644
|
+
// The rest measured as the text that opens the next line (#770).
|
|
1645
|
+
const own = font !== undefined && token.ownPieces !== undefined ? ownRest(token, bp.charIndex, font) : undefined;
|
|
1646
|
+
const residual = own
|
|
1647
|
+
? ownRestBreaks(token, bp.charIndex, own)
|
|
1648
|
+
: (token.breakPoints ?? [])
|
|
1649
|
+
.filter((b) => b.charIndex > bp.charIndex)
|
|
1650
|
+
.map((b) => ({ ...b, charIndex: b.charIndex - bp.charIndex, widthBefore: b.widthBefore - bp.widthBefore }));
|
|
1511
1651
|
return {
|
|
1512
1652
|
head: mark !== '' && bp.replacesWidth !== undefined
|
|
1513
1653
|
? { ...flags, text: withLineEndHyphen(token.text.slice(0, bp.charIndex)), kind: 'text', width: bp.widthBefore - bp.replacesWidth + markWidth }
|
|
@@ -1517,17 +1657,27 @@ function splitToken(token, bp, mark, markWidth) {
|
|
|
1517
1657
|
...pieceScriptFields(token, bp.charIndex, token.text.length),
|
|
1518
1658
|
text: token.text.slice(bp.charIndex),
|
|
1519
1659
|
kind: 'text',
|
|
1520
|
-
width: token.width - bp.widthBefore,
|
|
1660
|
+
width: own ? own(token.text.length) : token.width - bp.widthBefore,
|
|
1521
1661
|
...(residual.length > 0 ? { breakPoints: residual, hyphenWidth: token.hyphenWidth } : {}),
|
|
1522
1662
|
...(token.bareBreaks ? { bareBreaks: true } : {}),
|
|
1523
1663
|
...(token.dashJoin ? { dashJoin: true } : {}),
|
|
1664
|
+
...(own ? { ownPieces: token.ownPieces } : {}),
|
|
1524
1665
|
},
|
|
1525
1666
|
};
|
|
1526
1667
|
}
|
|
1527
1668
|
/** `token` (the tail of a compound broken after its hyphen) opening with
|
|
1528
1669
|
* that hyphen repeated, `hyphenWidth` px wide; its break points move with
|
|
1529
1670
|
* it. */
|
|
1530
|
-
function withLeadingHyphen(token, hyphenWidth) {
|
|
1671
|
+
function withLeadingHyphen(token, hyphenWidth, font) {
|
|
1672
|
+
// A word measured as the text painted (#770): the hyphen is part of the
|
|
1673
|
+
// text the line opens with, and the word is measured with it.
|
|
1674
|
+
if (font !== undefined && token.ownPieces !== undefined) {
|
|
1675
|
+
const own = ownRest(token, 0, font, '-');
|
|
1676
|
+
const breakPoints = ownRestBreaks(token, 0, own, 1);
|
|
1677
|
+
const { breakPoints: _points, ...rest } = token;
|
|
1678
|
+
void _points;
|
|
1679
|
+
return { ...rest, text: `-${token.text}`, width: own(token.text.length), ...(breakPoints.length > 0 ? { breakPoints } : {}) };
|
|
1680
|
+
}
|
|
1531
1681
|
return {
|
|
1532
1682
|
...token,
|
|
1533
1683
|
text: `-${token.text}`,
|
|
@@ -1674,6 +1824,24 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1674
1824
|
if (options?.labelColumnPx !== undefined)
|
|
1675
1825
|
setLabelTabs(tokens, (t) => t.labelTab, options.labelColumnPx, (t, w) => { t.width = w; });
|
|
1676
1826
|
const repeatHyphen = options?.repeatHyphen === true;
|
|
1827
|
+
// Words whose halves at a line end are measured as the texts painted, in
|
|
1828
|
+
// a document shaped in its own language (#770, `RichToken.ownPieces`):
|
|
1829
|
+
// the font each is measured in, and the pieces of the rest of one that
|
|
1830
|
+
// opens a line, for the lines Knuth–Plass sets (`reconstructRichLines`).
|
|
1831
|
+
const ownTokens = tokens.some((t) => t.ownPieces !== undefined);
|
|
1832
|
+
const fontOfToken = (t) => tokenFont(t, normalFont, boldFont, italicFont, boldItalicFont);
|
|
1833
|
+
const ownFont = (t) => (t.ownPieces !== undefined ? fontOfToken(t) : undefined);
|
|
1834
|
+
const restPieces = (tokenIndex, from, cuts, lead) => {
|
|
1835
|
+
const token = tokens[tokenIndex];
|
|
1836
|
+
const width = ownRest(token, from, fontOfToken(token), lead);
|
|
1837
|
+
let before = 0;
|
|
1838
|
+
return cuts.map((to) => {
|
|
1839
|
+
const upTo = width(to);
|
|
1840
|
+
const piece = upTo - before;
|
|
1841
|
+
before = upTo;
|
|
1842
|
+
return piece;
|
|
1843
|
+
});
|
|
1844
|
+
};
|
|
1677
1845
|
const hasSmallCaps = tokens.some((t) => t.smallCaps);
|
|
1678
1846
|
const normalSpaceWidth = textAlign === 'justify' ? normalSpaceWidthFor(normalFont) + letterSpacingPx : 0;
|
|
1679
1847
|
if (tokens.length === 0) {
|
|
@@ -1704,6 +1872,9 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1704
1872
|
const minShrinkRatio = ragged ? 1 : options.minShrinkRatio ?? 0.8;
|
|
1705
1873
|
// The runt threshold counts word spaces on ragged text too.
|
|
1706
1874
|
const spaceWidth = ragged ? normalSpaceWidthFor(normalFont) + letterSpacingPx : normalSpaceWidth;
|
|
1875
|
+
// The rest of a word broken at a line end, as the text painted (#770).
|
|
1876
|
+
if (ownTokens)
|
|
1877
|
+
markRestShifts(tokens, fontOfToken, repeatHyphen);
|
|
1707
1878
|
const items = richTokensToItems(tokens, spaceWidth, maxStretchRatio, minShrinkRatio, repeatHyphen);
|
|
1708
1879
|
const lineWidthFn = lineWidthFunction(maxWidthPx, options);
|
|
1709
1880
|
const lineIndentFn = indentOf;
|
|
@@ -1729,7 +1900,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1729
1900
|
...(ragged && hyphenationZonePx !== undefined ? { hyphenationZone: hyphenationZonePx } : {}),
|
|
1730
1901
|
});
|
|
1731
1902
|
if (breaks.length > 0) {
|
|
1732
|
-
const kpLines = reconstructRichLines(items, breaks, tokens, lineHeightPx, lineWidthFn, lineIndentFn, normalSpaceWidth, textAlign, trackingPerChar, lineBaselineOffset(lineHeightPx, normalFont));
|
|
1903
|
+
const kpLines = reconstructRichLines(items, breaks, tokens, lineHeightPx, lineWidthFn, lineIndentFn, normalSpaceWidth, textAlign, trackingPerChar, lineBaselineOffset(lineHeightPx, normalFont), ownTokens ? restPieces : undefined);
|
|
1733
1904
|
if (!hasOverfullLine(kpLines, lineWidthFn, ragged)) {
|
|
1734
1905
|
if (hasSmallCaps)
|
|
1735
1906
|
expandSmallCaps(kpLines, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx);
|
|
@@ -1788,7 +1959,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1788
1959
|
const lineRepeated = repeatPending && tokens[tokenIdx]?.kind === 'text';
|
|
1789
1960
|
if (lineRepeated) {
|
|
1790
1961
|
const tail = tokens[tokenIdx];
|
|
1791
|
-
tokens[tokenIdx] = withLeadingHyphen(tail, tail.hyphenWidth ?? measureTextWidth('-', tokenFont(tail, normalFont, boldFont, italicFont, boldItalicFont)) + letterSpacingPx);
|
|
1962
|
+
tokens[tokenIdx] = withLeadingHyphen(tail, tail.hyphenWidth ?? measureTextWidth('-', tokenFont(tail, normalFont, boldFont, italicFont, boldItalicFont)) + letterSpacingPx, ownFont(tail));
|
|
1792
1963
|
}
|
|
1793
1964
|
repeatPending = false;
|
|
1794
1965
|
// This line ends after a compound's hyphen the next one repeats.
|
|
@@ -1881,7 +2052,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1881
2052
|
}
|
|
1882
2053
|
if (chosen) {
|
|
1883
2054
|
const mark = plainBreak(chosen) ? '' : '-';
|
|
1884
|
-
const split = splitToken(token, chosen, mark, markW(chosen));
|
|
2055
|
+
const split = splitToken(token, chosen, mark, markW(chosen), ownFont(token));
|
|
1885
2056
|
lineTokens.push(split.head);
|
|
1886
2057
|
lineWidth += split.head.width;
|
|
1887
2058
|
lineHyphenated = chosen.cjk !== true;
|
|
@@ -1936,7 +2107,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1936
2107
|
const origIdx = tokenIdx - (lineTokens.length - back.at);
|
|
1937
2108
|
while (lineTokens.length > back.at)
|
|
1938
2109
|
lineWidth -= lineTokens.pop().width;
|
|
1939
|
-
const split = splitToken(back.token, back.bp, '', 0);
|
|
2110
|
+
const split = splitToken(back.token, back.bp, '', 0, ownFont(back.token));
|
|
1940
2111
|
lineTokens.push(split.head);
|
|
1941
2112
|
lineWidth += split.head.width;
|
|
1942
2113
|
tokens[origIdx] = split.tail;
|
|
@@ -1976,7 +2147,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1976
2147
|
const origIdx = tokenIdx - (lineTokens.length - syllable.at);
|
|
1977
2148
|
while (lineTokens.length > syllable.at)
|
|
1978
2149
|
lineWidth -= lineTokens.pop().width;
|
|
1979
|
-
const split = splitToken(syllable.token, syllable.bp, '-', syllable.token.hyphenWidth ?? 0);
|
|
2150
|
+
const split = splitToken(syllable.token, syllable.bp, '-', syllable.token.hyphenWidth ?? 0, ownFont(syllable.token));
|
|
1980
2151
|
lineTokens.push(split.head);
|
|
1981
2152
|
lineWidth += split.head.width;
|
|
1982
2153
|
tokens[origIdx] = split.tail;
|