postext 1.8.6 → 1.9.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/__bench__/cjkChapter.bench.test.d.ts +2 -0
- package/dist/__bench__/cjkChapter.bench.test.d.ts.map +1 -0
- package/dist/__bench__/cjkChapter.bench.test.js +71 -0
- package/dist/__bench__/cjkChapter.bench.test.js.map +1 -0
- package/dist/__tests__/bundle.test.js +16 -0
- package/dist/__tests__/bundle.test.js.map +1 -1
- package/dist/__tests__/canvasDirection.test.d.ts +2 -0
- package/dist/__tests__/canvasDirection.test.d.ts.map +1 -0
- package/dist/__tests__/canvasDirection.test.js +45 -0
- package/dist/__tests__/canvasDirection.test.js.map +1 -0
- package/dist/__tests__/chineseLocale.test.d.ts +2 -0
- package/dist/__tests__/chineseLocale.test.d.ts.map +1 -0
- package/dist/__tests__/chineseLocale.test.js +253 -0
- package/dist/__tests__/chineseLocale.test.js.map +1 -0
- package/dist/__tests__/chineseNumbering.test.d.ts +2 -0
- package/dist/__tests__/chineseNumbering.test.d.ts.map +1 -0
- package/dist/__tests__/chineseNumbering.test.js +376 -0
- package/dist/__tests__/chineseNumbering.test.js.map +1 -0
- package/dist/__tests__/cjk/annotations.test.d.ts +2 -0
- package/dist/__tests__/cjk/annotations.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/annotations.test.js +483 -0
- package/dist/__tests__/cjk/annotations.test.js.map +1 -0
- package/dist/__tests__/cjk/annotationsRender.test.d.ts +2 -0
- package/dist/__tests__/cjk/annotationsRender.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/annotationsRender.test.js +263 -0
- package/dist/__tests__/cjk/annotationsRender.test.js.map +1 -0
- package/dist/__tests__/cjk/composer.test.d.ts +2 -0
- package/dist/__tests__/cjk/composer.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/composer.test.js +237 -0
- package/dist/__tests__/cjk/composer.test.js.map +1 -0
- package/dist/__tests__/cjk/composerEdges.test.d.ts +2 -0
- package/dist/__tests__/cjk/composerEdges.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/composerEdges.test.js +352 -0
- package/dist/__tests__/cjk/composerEdges.test.js.map +1 -0
- package/dist/__tests__/cjk/dashRule.test.d.ts +2 -0
- package/dist/__tests__/cjk/dashRule.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/dashRule.test.js +261 -0
- package/dist/__tests__/cjk/dashRule.test.js.map +1 -0
- package/dist/__tests__/cjk/fuzz.test.d.ts +2 -0
- package/dist/__tests__/cjk/fuzz.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/fuzz.test.js +102 -0
- package/dist/__tests__/cjk/fuzz.test.js.map +1 -0
- package/dist/__tests__/cjk/grid.test.d.ts +2 -0
- package/dist/__tests__/cjk/grid.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/grid.test.js +261 -0
- package/dist/__tests__/cjk/grid.test.js.map +1 -0
- package/dist/__tests__/cjk/justifyRender.test.d.ts +2 -0
- package/dist/__tests__/cjk/justifyRender.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/justifyRender.test.js +139 -0
- package/dist/__tests__/cjk/justifyRender.test.js.map +1 -0
- package/dist/__tests__/cjk/latinFastPath.test.d.ts +2 -0
- package/dist/__tests__/cjk/latinFastPath.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/latinFastPath.test.js +208 -0
- package/dist/__tests__/cjk/latinFastPath.test.js.map +1 -0
- package/dist/__tests__/cjk/markCutsLatin.test.d.ts +2 -0
- package/dist/__tests__/cjk/markCutsLatin.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/markCutsLatin.test.js +69 -0
- package/dist/__tests__/cjk/markCutsLatin.test.js.map +1 -0
- package/dist/__tests__/cjk/markRuns.test.d.ts +2 -0
- package/dist/__tests__/cjk/markRuns.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/markRuns.test.js +347 -0
- package/dist/__tests__/cjk/markRuns.test.js.map +1 -0
- package/dist/__tests__/cjk/punctuation.test.d.ts +2 -0
- package/dist/__tests__/cjk/punctuation.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/punctuation.test.js +440 -0
- package/dist/__tests__/cjk/punctuation.test.js.map +1 -0
- package/dist/__tests__/cjk/punctuationRender.test.d.ts +2 -0
- package/dist/__tests__/cjk/punctuationRender.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/punctuationRender.test.js +135 -0
- package/dist/__tests__/cjk/punctuationRender.test.js.map +1 -0
- package/dist/__tests__/cjk/rubyDescenders.test.d.ts +2 -0
- package/dist/__tests__/cjk/rubyDescenders.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/rubyDescenders.test.js +77 -0
- package/dist/__tests__/cjk/rubyDescenders.test.js.map +1 -0
- package/dist/__tests__/cjk/runt.test.d.ts +2 -0
- package/dist/__tests__/cjk/runt.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/runt.test.js +103 -0
- package/dist/__tests__/cjk/runt.test.js.map +1 -0
- package/dist/__tests__/cjk/sharedMarks.test.d.ts +2 -0
- package/dist/__tests__/cjk/sharedMarks.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/sharedMarks.test.js +347 -0
- package/dist/__tests__/cjk/sharedMarks.test.js.map +1 -0
- package/dist/__tests__/cjk/uprightDots.test.d.ts +2 -0
- package/dist/__tests__/cjk/uprightDots.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/uprightDots.test.js +47 -0
- package/dist/__tests__/cjk/uprightDots.test.js.map +1 -0
- package/dist/__tests__/cjk/wordJoiner.test.d.ts +2 -0
- package/dist/__tests__/cjk/wordJoiner.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/wordJoiner.test.js +47 -0
- package/dist/__tests__/cjk/wordJoiner.test.js.map +1 -0
- package/dist/__tests__/cjk/zhuyinTones.test.d.ts +2 -0
- package/dist/__tests__/cjk/zhuyinTones.test.d.ts.map +1 -0
- package/dist/__tests__/cjk/zhuyinTones.test.js +72 -0
- package/dist/__tests__/cjk/zhuyinTones.test.js.map +1 -0
- package/dist/__tests__/contentLocale.test.d.ts +2 -0
- package/dist/__tests__/contentLocale.test.d.ts.map +1 -0
- package/dist/__tests__/contentLocale.test.js +167 -0
- package/dist/__tests__/contentLocale.test.js.map +1 -0
- package/dist/__tests__/defaults/cjk.test.d.ts +2 -0
- package/dist/__tests__/defaults/cjk.test.d.ts.map +1 -0
- package/dist/__tests__/defaults/cjk.test.js +70 -0
- package/dist/__tests__/defaults/cjk.test.js.map +1 -0
- package/dist/__tests__/design/designTextRender.test.js +31 -0
- package/dist/__tests__/design/designTextRender.test.js.map +1 -1
- package/dist/__tests__/design/imageAltText.test.d.ts +2 -0
- package/dist/__tests__/design/imageAltText.test.d.ts.map +1 -0
- package/dist/__tests__/design/imageAltText.test.js +126 -0
- package/dist/__tests__/design/imageAltText.test.js.map +1 -0
- package/dist/__tests__/exports.test.js +61 -0
- package/dist/__tests__/exports.test.js.map +1 -1
- package/dist/__tests__/headingLetterSpacing.test.js +1 -1
- package/dist/__tests__/headingLetterSpacing.test.js.map +1 -1
- package/dist/__tests__/indexChinese.test.d.ts +2 -0
- package/dist/__tests__/indexChinese.test.d.ts.map +1 -0
- package/dist/__tests__/indexChinese.test.js +190 -0
- package/dist/__tests__/indexChinese.test.js.map +1 -0
- package/dist/__tests__/parse/annotations.test.d.ts +2 -0
- package/dist/__tests__/parse/annotations.test.d.ts.map +1 -0
- package/dist/__tests__/parse/annotations.test.js +175 -0
- package/dist/__tests__/parse/annotations.test.js.map +1 -0
- package/dist/__tests__/parse/attrQuoting.test.js +10 -8
- package/dist/__tests__/parse/attrQuoting.test.js.map +1 -1
- package/dist/__tests__/parse/chineseText.test.d.ts +2 -0
- package/dist/__tests__/parse/chineseText.test.d.ts.map +1 -0
- package/dist/__tests__/parse/chineseText.test.js +352 -0
- package/dist/__tests__/parse/chineseText.test.js.map +1 -0
- package/dist/__tests__/parts.test.js +25 -0
- package/dist/__tests__/parts.test.js.map +1 -1
- package/dist/__tests__/pipeline/colonListRoom.test.js +20 -0
- package/dist/__tests__/pipeline/colonListRoom.test.js.map +1 -1
- package/dist/__tests__/presets/hongloumeng.test.d.ts +2 -0
- package/dist/__tests__/presets/hongloumeng.test.d.ts.map +1 -0
- package/dist/__tests__/presets/hongloumeng.test.js +484 -0
- package/dist/__tests__/presets/hongloumeng.test.js.map +1 -0
- package/dist/__tests__/vertical/canvasPaint.test.d.ts +2 -0
- package/dist/__tests__/vertical/canvasPaint.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/canvasPaint.test.js +229 -0
- package/dist/__tests__/vertical/canvasPaint.test.js.map +1 -0
- package/dist/__tests__/vertical/compositionPaint.test.d.ts +2 -0
- package/dist/__tests__/vertical/compositionPaint.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/compositionPaint.test.js +538 -0
- package/dist/__tests__/vertical/compositionPaint.test.js.map +1 -0
- package/dist/__tests__/vertical/geometry.test.d.ts +2 -0
- package/dist/__tests__/vertical/geometry.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/geometry.test.js +276 -0
- package/dist/__tests__/vertical/geometry.test.js.map +1 -0
- package/dist/__tests__/vertical/htmlSmoke.test.d.ts +2 -0
- package/dist/__tests__/vertical/htmlSmoke.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/htmlSmoke.test.js +25 -0
- package/dist/__tests__/vertical/htmlSmoke.test.js.map +1 -0
- package/dist/__tests__/vertical/htmlTurnedCells.test.d.ts +2 -0
- package/dist/__tests__/vertical/htmlTurnedCells.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/htmlTurnedCells.test.js +99 -0
- package/dist/__tests__/vertical/htmlTurnedCells.test.js.map +1 -0
- package/dist/__tests__/vertical/htmlVertical.test.d.ts +2 -0
- package/dist/__tests__/vertical/htmlVertical.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/htmlVertical.test.js +145 -0
- package/dist/__tests__/vertical/htmlVertical.test.js.map +1 -0
- package/dist/__tests__/vertical/lineAxis.test.d.ts +2 -0
- package/dist/__tests__/vertical/lineAxis.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/lineAxis.test.js +128 -0
- package/dist/__tests__/vertical/lineAxis.test.js.map +1 -0
- package/dist/__tests__/vertical/measurePaint.test.d.ts +2 -0
- package/dist/__tests__/vertical/measurePaint.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/measurePaint.test.js +259 -0
- package/dist/__tests__/vertical/measurePaint.test.js.map +1 -0
- package/dist/__tests__/vertical/orientation.test.d.ts +2 -0
- package/dist/__tests__/vertical/orientation.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/orientation.test.js +153 -0
- package/dist/__tests__/vertical/orientation.test.js.map +1 -0
- package/dist/__tests__/vertical/stub.d.ts +8 -0
- package/dist/__tests__/vertical/stub.d.ts.map +1 -0
- package/dist/__tests__/vertical/stub.js +37 -0
- package/dist/__tests__/vertical/stub.js.map +1 -0
- package/dist/__tests__/vertical/tateChuYoko.test.d.ts +2 -0
- package/dist/__tests__/vertical/tateChuYoko.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/tateChuYoko.test.js +270 -0
- package/dist/__tests__/vertical/tateChuYoko.test.js.map +1 -0
- package/dist/__tests__/vertical/uprightResources.test.d.ts +2 -0
- package/dist/__tests__/vertical/uprightResources.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/uprightResources.test.js +182 -0
- package/dist/__tests__/vertical/uprightResources.test.js.map +1 -0
- package/dist/__tests__/vertical/verticalDesignText.test.d.ts +2 -0
- package/dist/__tests__/vertical/verticalDesignText.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/verticalDesignText.test.js +190 -0
- package/dist/__tests__/vertical/verticalDesignText.test.js.map +1 -0
- package/dist/__tests__/vertical/verticalSpans.d.ts +25 -0
- package/dist/__tests__/vertical/verticalSpans.d.ts.map +1 -0
- package/dist/__tests__/vertical/verticalSpans.js +39 -0
- package/dist/__tests__/vertical/verticalSpans.js.map +1 -0
- package/dist/__tests__/vertical/verticalTwins.test.d.ts +2 -0
- package/dist/__tests__/vertical/verticalTwins.test.d.ts.map +1 -0
- package/dist/__tests__/vertical/verticalTwins.test.js +71 -0
- package/dist/__tests__/vertical/verticalTwins.test.js.map +1 -0
- package/dist/bundle/adapters.d.ts +14 -5
- package/dist/bundle/adapters.d.ts.map +1 -1
- package/dist/bundle/adapters.js +4 -3
- package/dist/bundle/adapters.js.map +1 -1
- package/dist/bundle/codec.d.ts.map +1 -1
- package/dist/bundle/codec.js +27 -4
- package/dist/bundle/codec.js.map +1 -1
- package/dist/bundle/index.d.ts +1 -1
- package/dist/bundle/index.d.ts.map +1 -1
- package/dist/bundle/manifest.d.ts +6 -4
- package/dist/bundle/manifest.d.ts.map +1 -1
- package/dist/bundle/manifest.js +31 -32
- package/dist/bundle/manifest.js.map +1 -1
- package/dist/bundle/types.d.ts +7 -2
- package/dist/bundle/types.d.ts.map +1 -1
- package/dist/canvas-backend/annotations.d.ts +31 -0
- package/dist/canvas-backend/annotations.d.ts.map +1 -0
- package/dist/canvas-backend/annotations.js +120 -0
- package/dist/canvas-backend/annotations.js.map +1 -0
- package/dist/canvas-backend/blockRender.d.ts.map +1 -1
- package/dist/canvas-backend/blockRender.js +195 -15
- package/dist/canvas-backend/blockRender.js.map +1 -1
- package/dist/canvas-backend/decorations.d.ts +5 -0
- package/dist/canvas-backend/decorations.d.ts.map +1 -1
- package/dist/canvas-backend/decorations.js +27 -0
- package/dist/canvas-backend/decorations.js.map +1 -1
- package/dist/canvas-backend/headerFooter.d.ts.map +1 -1
- package/dist/canvas-backend/headerFooter.js +32 -16
- package/dist/canvas-backend/headerFooter.js.map +1 -1
- package/dist/canvas-backend/index.d.ts +2 -0
- package/dist/canvas-backend/index.d.ts.map +1 -1
- package/dist/canvas-backend/index.js +62 -2
- 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 +42 -5
- package/dist/canvas-backend/renderResourceBlock.js.map +1 -1
- package/dist/canvas-backend/segmentText.d.ts +23 -0
- package/dist/canvas-backend/segmentText.d.ts.map +1 -0
- package/dist/canvas-backend/segmentText.js +41 -0
- package/dist/canvas-backend/segmentText.js.map +1 -0
- package/dist/canvas-backend/verticalText.d.ts +113 -0
- package/dist/canvas-backend/verticalText.d.ts.map +1 -0
- package/dist/canvas-backend/verticalText.js +437 -0
- package/dist/canvas-backend/verticalText.js.map +1 -0
- package/dist/chineseNumerals.d.ts +39 -0
- package/dist/chineseNumerals.d.ts.map +1 -0
- package/dist/chineseNumerals.js +192 -0
- package/dist/chineseNumerals.js.map +1 -0
- package/dist/cjkMarks.d.ts +61 -0
- package/dist/cjkMarks.d.ts.map +1 -0
- package/dist/cjkMarks.js +441 -0
- package/dist/cjkMarks.js.map +1 -0
- package/dist/columnClip.d.ts +13 -4
- package/dist/columnClip.d.ts.map +1 -1
- package/dist/columnClip.js +33 -5
- package/dist/columnClip.js.map +1 -1
- package/dist/configWarnings.d.ts.map +1 -1
- package/dist/configWarnings.js +18 -3
- package/dist/configWarnings.js.map +1 -1
- package/dist/defaults/bodyText.d.ts +4 -1
- package/dist/defaults/bodyText.d.ts.map +1 -1
- package/dist/defaults/bodyText.js +27 -5
- package/dist/defaults/bodyText.js.map +1 -1
- package/dist/defaults/calloutStyles.js +1 -1
- package/dist/defaults/calloutStyles.js.map +1 -1
- package/dist/defaults/captionStyle.d.ts.map +1 -1
- package/dist/defaults/captionStyle.js +14 -0
- package/dist/defaults/captionStyle.js.map +1 -1
- package/dist/defaults/cjk.d.ts +33 -0
- package/dist/defaults/cjk.d.ts.map +1 -0
- package/dist/defaults/cjk.js +234 -0
- package/dist/defaults/cjk.js.map +1 -0
- package/dist/defaults/headerFooter.d.ts.map +1 -1
- package/dist/defaults/headerFooter.js +2 -0
- package/dist/defaults/headerFooter.js.map +1 -1
- package/dist/defaults/headingStyles.d.ts.map +1 -1
- package/dist/defaults/headingStyles.js +4 -0
- package/dist/defaults/headingStyles.js.map +1 -1
- package/dist/defaults/headings.d.ts.map +1 -1
- package/dist/defaults/headings.js +13 -6
- package/dist/defaults/headings.js.map +1 -1
- package/dist/defaults/index.d.ts +1 -0
- package/dist/defaults/index.d.ts.map +1 -1
- package/dist/defaults/index.js +10 -1
- package/dist/defaults/index.js.map +1 -1
- package/dist/defaults/indexConfig.d.ts +2 -1
- package/dist/defaults/indexConfig.d.ts.map +1 -1
- package/dist/defaults/indexConfig.js +5 -0
- package/dist/defaults/indexConfig.js.map +1 -1
- package/dist/defaults/layout.d.ts.map +1 -1
- package/dist/defaults/layout.js +7 -0
- package/dist/defaults/layout.js.map +1 -1
- package/dist/defaults/orderedLists.d.ts +5 -2
- package/dist/defaults/orderedLists.d.ts.map +1 -1
- package/dist/defaults/orderedLists.js +20 -5
- package/dist/defaults/orderedLists.js.map +1 -1
- package/dist/defaults/page.d.ts +8 -2
- package/dist/defaults/page.d.ts.map +1 -1
- package/dist/defaults/page.js +24 -7
- package/dist/defaults/page.js.map +1 -1
- package/dist/defaults/resourceTypes.d.ts +3 -3
- package/dist/defaults/resourceTypes.d.ts.map +1 -1
- package/dist/defaults/resourceTypes.js +23 -9
- package/dist/defaults/resourceTypes.js.map +1 -1
- package/dist/defaults/tableStyle.d.ts.map +1 -1
- package/dist/defaults/tableStyle.js +8 -5
- package/dist/defaults/tableStyle.js.map +1 -1
- package/dist/design/layout.d.ts +33 -0
- package/dist/design/layout.d.ts.map +1 -1
- package/dist/design/layout.js +124 -18
- package/dist/design/layout.js.map +1 -1
- package/dist/design/placeholders.d.ts.map +1 -1
- package/dist/design/placeholders.js +5 -1
- package/dist/design/placeholders.js.map +1 -1
- package/dist/design/richText.d.ts +24 -4
- package/dist/design/richText.d.ts.map +1 -1
- package/dist/design/richText.js +77 -16
- package/dist/design/richText.js.map +1 -1
- package/dist/html-backend.d.ts.map +1 -1
- package/dist/html-backend.js +635 -25
- package/dist/html-backend.js.map +1 -1
- package/dist/htmlAnnotations.d.ts +29 -0
- package/dist/htmlAnnotations.d.ts.map +1 -0
- package/dist/htmlAnnotations.js +86 -0
- package/dist/htmlAnnotations.js.map +1 -0
- package/dist/hyphenate.js +2 -1
- package/dist/hyphenate.js.map +1 -1
- package/dist/index.d.ts +28 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -8
- package/dist/index.js.map +1 -1
- package/dist/knuthPlass/pretextAdapter.d.ts +4 -1
- package/dist/knuthPlass/pretextAdapter.d.ts.map +1 -1
- package/dist/knuthPlass/pretextAdapter.js +9 -5
- package/dist/knuthPlass/pretextAdapter.js.map +1 -1
- package/dist/knuthPlass/richAdapter.d.ts +15 -2
- package/dist/knuthPlass/richAdapter.d.ts.map +1 -1
- package/dist/knuthPlass/richAdapter.js +16 -6
- package/dist/knuthPlass/richAdapter.js.map +1 -1
- package/dist/knuthPlass/tracking.d.ts +1 -1
- package/dist/knuthPlass/tracking.d.ts.map +1 -1
- package/dist/knuthPlass/tracking.js +4 -3
- package/dist/knuthPlass/tracking.js.map +1 -1
- package/dist/knuthPlass/types.d.ts +3 -0
- package/dist/knuthPlass/types.d.ts.map +1 -1
- package/dist/lineInk.d.ts +13 -0
- package/dist/lineInk.d.ts.map +1 -1
- package/dist/lineInk.js +28 -1
- package/dist/lineInk.js.map +1 -1
- package/dist/locale.d.ts +91 -3
- package/dist/locale.d.ts.map +1 -1
- package/dist/locale.js +245 -1
- package/dist/locale.js.map +1 -1
- package/dist/looseLines.d.ts +11 -1
- package/dist/looseLines.d.ts.map +1 -1
- package/dist/looseLines.js +26 -1
- package/dist/looseLines.js.map +1 -1
- package/dist/measure/cache.d.ts.map +1 -1
- package/dist/measure/cache.js +51 -3
- package/dist/measure/cache.js.map +1 -1
- package/dist/measure/canvas.d.ts +25 -0
- package/dist/measure/canvas.d.ts.map +1 -1
- package/dist/measure/canvas.js +90 -1
- package/dist/measure/canvas.js.map +1 -1
- package/dist/measure/cjk.d.ts +8 -13
- package/dist/measure/cjk.d.ts.map +1 -1
- package/dist/measure/cjk.js +29 -53
- package/dist/measure/cjk.js.map +1 -1
- package/dist/measure/cjkAnnotate.d.ts +96 -0
- package/dist/measure/cjkAnnotate.d.ts.map +1 -0
- package/dist/measure/cjkAnnotate.js +237 -0
- package/dist/measure/cjkAnnotate.js.map +1 -0
- package/dist/measure/cjkClasses.d.ts +133 -0
- package/dist/measure/cjkClasses.d.ts.map +1 -0
- package/dist/measure/cjkClasses.js +273 -0
- package/dist/measure/cjkClasses.js.map +1 -0
- package/dist/measure/cjkCompose.d.ts +86 -0
- package/dist/measure/cjkCompose.d.ts.map +1 -0
- package/dist/measure/cjkCompose.js +2022 -0
- package/dist/measure/cjkCompose.js.map +1 -0
- package/dist/measure/cjkPunctuation.d.ts +248 -0
- package/dist/measure/cjkPunctuation.d.ts.map +1 -0
- package/dist/measure/cjkPunctuation.js +492 -0
- package/dist/measure/cjkPunctuation.js.map +1 -0
- package/dist/measure/graphemes.d.ts +13 -0
- package/dist/measure/graphemes.d.ts.map +1 -0
- package/dist/measure/graphemes.js +38 -0
- package/dist/measure/graphemes.js.map +1 -0
- package/dist/measure/index.d.ts +3 -0
- package/dist/measure/index.d.ts.map +1 -1
- package/dist/measure/index.js +2 -0
- package/dist/measure/index.js.map +1 -1
- package/dist/measure/links.d.ts +6 -2
- package/dist/measure/links.d.ts.map +1 -1
- package/dist/measure/links.js +15 -5
- package/dist/measure/links.js.map +1 -1
- package/dist/measure/markCuts.d.ts +37 -0
- package/dist/measure/markCuts.d.ts.map +1 -0
- package/dist/measure/markCuts.js +77 -0
- package/dist/measure/markCuts.js.map +1 -0
- package/dist/measure/plain.d.ts.map +1 -1
- package/dist/measure/plain.js +33 -11
- package/dist/measure/plain.js.map +1 -1
- package/dist/measure/rich.d.ts +88 -1
- package/dist/measure/rich.d.ts.map +1 -1
- package/dist/measure/rich.js +233 -111
- package/dist/measure/rich.js.map +1 -1
- package/dist/measure/rubyLift.d.ts +11 -0
- package/dist/measure/rubyLift.d.ts.map +1 -0
- package/dist/measure/rubyLift.js +57 -0
- package/dist/measure/rubyLift.js.map +1 -0
- package/dist/measure/spaces.d.ts +12 -2
- package/dist/measure/spaces.d.ts.map +1 -1
- package/dist/measure/spaces.js +21 -7
- package/dist/measure/spaces.js.map +1 -1
- package/dist/measure/types.d.ts +20 -1
- package/dist/measure/types.d.ts.map +1 -1
- package/dist/measure/types.js.map +1 -1
- package/dist/measure/vertical.d.ts +104 -0
- package/dist/measure/vertical.d.ts.map +1 -0
- package/dist/measure/vertical.js +184 -0
- package/dist/measure/vertical.js.map +1 -0
- package/dist/numberWords.d.ts +3 -10
- package/dist/numberWords.d.ts.map +1 -1
- package/dist/numberWords.js +21 -9
- package/dist/numberWords.js.map +1 -1
- package/dist/numbering.d.ts +23 -5
- package/dist/numbering.d.ts.map +1 -1
- package/dist/numbering.js +99 -14
- package/dist/numbering.js.map +1 -1
- package/dist/parse/annotations.d.ts +101 -0
- package/dist/parse/annotations.d.ts.map +1 -0
- package/dist/parse/annotations.js +556 -0
- package/dist/parse/annotations.js.map +1 -0
- package/dist/parse/attrs.d.ts +48 -1
- package/dist/parse/attrs.d.ts.map +1 -1
- package/dist/parse/attrs.js +121 -8
- package/dist/parse/attrs.js.map +1 -1
- package/dist/parse/blockParser.d.ts.map +1 -1
- package/dist/parse/blockParser.js +50 -24
- package/dist/parse/blockParser.js.map +1 -1
- package/dist/parse/index.d.ts +3 -1
- package/dist/parse/index.d.ts.map +1 -1
- package/dist/parse/index.js +1 -0
- package/dist/parse/index.js.map +1 -1
- package/dist/parse/injectSpans.d.ts +3 -1
- package/dist/parse/injectSpans.d.ts.map +1 -1
- package/dist/parse/injectSpans.js +29 -8
- package/dist/parse/injectSpans.js.map +1 -1
- package/dist/parse/inlineFormatting.d.ts +38 -6
- package/dist/parse/inlineFormatting.d.ts.map +1 -1
- package/dist/parse/inlineFormatting.js +139 -26
- package/dist/parse/inlineFormatting.js.map +1 -1
- package/dist/parse/inlineSnippet.d.ts +2 -1
- package/dist/parse/inlineSnippet.d.ts.map +1 -1
- package/dist/parse/inlineSnippet.js +6 -2
- package/dist/parse/inlineSnippet.js.map +1 -1
- package/dist/parse/orientationMarks.d.ts +49 -0
- package/dist/parse/orientationMarks.d.ts.map +1 -0
- package/dist/parse/orientationMarks.js +138 -0
- package/dist/parse/orientationMarks.js.map +1 -0
- package/dist/parse/softBreaks.d.ts +56 -0
- package/dist/parse/softBreaks.d.ts.map +1 -0
- package/dist/parse/softBreaks.js +271 -0
- package/dist/parse/softBreaks.js.map +1 -0
- package/dist/parse/sourceMapping.d.ts.map +1 -1
- package/dist/parse/sourceMapping.js +41 -0
- package/dist/parse/sourceMapping.js.map +1 -1
- package/dist/parse/types.d.ts +84 -0
- package/dist/parse/types.d.ts.map +1 -1
- package/dist/pipeline/annotations.d.ts +56 -0
- package/dist/pipeline/annotations.d.ts.map +1 -0
- package/dist/pipeline/annotations.js +181 -0
- package/dist/pipeline/annotations.js.map +1 -0
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +158 -47
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/buildBlockKind.d.ts +3 -0
- package/dist/pipeline/buildBlockKind.d.ts.map +1 -1
- package/dist/pipeline/buildBlockKind.js +5 -3
- package/dist/pipeline/buildBlockKind.js.map +1 -1
- package/dist/pipeline/buildHelpers.d.ts +36 -6
- package/dist/pipeline/buildHelpers.d.ts.map +1 -1
- package/dist/pipeline/buildHelpers.js +55 -8
- package/dist/pipeline/buildHelpers.js.map +1 -1
- package/dist/pipeline/buildMeasurement.d.ts +4 -0
- package/dist/pipeline/buildMeasurement.d.ts.map +1 -1
- package/dist/pipeline/buildMeasurement.js +3 -1
- package/dist/pipeline/buildMeasurement.js.map +1 -1
- package/dist/pipeline/calloutLayout.d.ts.map +1 -1
- package/dist/pipeline/calloutLayout.js +25 -11
- package/dist/pipeline/calloutLayout.js.map +1 -1
- package/dist/pipeline/cjkGrid.d.ts +133 -0
- package/dist/pipeline/cjkGrid.d.ts.map +1 -0
- package/dist/pipeline/cjkGrid.js +191 -0
- package/dist/pipeline/cjkGrid.js.map +1 -0
- package/dist/pipeline/config.d.ts +13 -9
- package/dist/pipeline/config.d.ts.map +1 -1
- package/dist/pipeline/config.js +43 -18
- package/dist/pipeline/config.js.map +1 -1
- package/dist/pipeline/contentWarnings.d.ts +10 -0
- package/dist/pipeline/contentWarnings.d.ts.map +1 -1
- package/dist/pipeline/contentWarnings.js +174 -2
- package/dist/pipeline/contentWarnings.js.map +1 -1
- package/dist/pipeline/floatPlacement.d.ts +9 -3
- package/dist/pipeline/floatPlacement.d.ts.map +1 -1
- package/dist/pipeline/floatPlacement.js +17 -6
- package/dist/pipeline/floatPlacement.js.map +1 -1
- package/dist/pipeline/headerFooter.d.ts +5 -2
- package/dist/pipeline/headerFooter.d.ts.map +1 -1
- package/dist/pipeline/headerFooter.js +123 -28
- package/dist/pipeline/headerFooter.js.map +1 -1
- package/dist/pipeline/headingDesignCuts.d.ts.map +1 -1
- package/dist/pipeline/headingDesignCuts.js +3 -1
- package/dist/pipeline/headingDesignCuts.js.map +1 -1
- package/dist/pipeline/headingStyles.d.ts +9 -3
- package/dist/pipeline/headingStyles.d.ts.map +1 -1
- package/dist/pipeline/headingStyles.js +23 -5
- package/dist/pipeline/headingStyles.js.map +1 -1
- package/dist/pipeline/indexDirective.d.ts.map +1 -1
- package/dist/pipeline/indexDirective.js +64 -20
- package/dist/pipeline/indexDirective.js.map +1 -1
- package/dist/pipeline/indexGroups.d.ts +55 -0
- package/dist/pipeline/indexGroups.d.ts.map +1 -0
- package/dist/pipeline/indexGroups.js +151 -0
- package/dist/pipeline/indexGroups.js.map +1 -0
- package/dist/pipeline/lists.d.ts +17 -0
- package/dist/pipeline/lists.d.ts.map +1 -1
- package/dist/pipeline/lists.js +43 -51
- package/dist/pipeline/lists.js.map +1 -1
- package/dist/pipeline/measureContentBlock.d.ts +3 -0
- package/dist/pipeline/measureContentBlock.d.ts.map +1 -1
- package/dist/pipeline/measureContentBlock.js +31 -4
- package/dist/pipeline/measureContentBlock.js.map +1 -1
- package/dist/pipeline/outline.d.ts.map +1 -1
- package/dist/pipeline/outline.js +13 -8
- package/dist/pipeline/outline.js.map +1 -1
- package/dist/pipeline/parts.d.ts +6 -3
- package/dist/pipeline/parts.d.ts.map +1 -1
- package/dist/pipeline/parts.js +28 -5
- package/dist/pipeline/parts.js.map +1 -1
- package/dist/pipeline/placeholders.d.ts +11 -0
- package/dist/pipeline/placeholders.d.ts.map +1 -1
- package/dist/pipeline/placeholders.js +48 -18
- package/dist/pipeline/placeholders.js.map +1 -1
- package/dist/pipeline/placement.d.ts +10 -6
- package/dist/pipeline/placement.d.ts.map +1 -1
- package/dist/pipeline/placement.js +33 -16
- package/dist/pipeline/placement.js.map +1 -1
- package/dist/pipeline/resourceLayout.d.ts +18 -1
- package/dist/pipeline/resourceLayout.d.ts.map +1 -1
- package/dist/pipeline/resourceLayout.js +109 -21
- package/dist/pipeline/resourceLayout.js.map +1 -1
- package/dist/pipeline/toc.d.ts.map +1 -1
- package/dist/pipeline/toc.js +6 -5
- package/dist/pipeline/toc.js.map +1 -1
- package/dist/pipeline/verticalMetrics.d.ts +14 -0
- package/dist/pipeline/verticalMetrics.d.ts.map +1 -0
- package/dist/pipeline/verticalMetrics.js +154 -0
- package/dist/pipeline/verticalMetrics.js.map +1 -0
- package/dist/types.d.ts +344 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/vdt.d.ts +396 -6
- package/dist/vdt.d.ts.map +1 -1
- package/dist/vdt.js +49 -0
- package/dist/vdt.js.map +1 -1
- package/dist/writingMode.d.ts +156 -0
- package/dist/writingMode.d.ts.map +1 -0
- package/dist/writingMode.js +291 -0
- package/dist/writingMode.js.map +1 -0
- package/package.json +1 -1
package/dist/measure/rich.js
CHANGED
|
@@ -8,7 +8,10 @@ import { isRuntLastLine } from './runts';
|
|
|
8
8
|
import { computeJustifiedSpaceRatio, hasOverfullLine } from './plain';
|
|
9
9
|
import { quoteFamily } from './font';
|
|
10
10
|
import { trimChipLineEdges } from './chipEdges';
|
|
11
|
-
import {
|
|
11
|
+
import { cjkJoinBreaks, hasCJK } from './cjk';
|
|
12
|
+
import { composeCjkParagraph, cjkWordBreaks, composesAsCjk, spanMarks } from './cjkCompose';
|
|
13
|
+
import { graphemeCount } from './graphemes';
|
|
14
|
+
import { fontEm, getMeasureUprightDigits, getMeasureWritingMode, lineBaselineOffset, measuringVertically, verticalTextWidth, withMeasureWritingMode } from './vertical';
|
|
12
15
|
import { NO_BREAK_SPACES, WORDS_AND_SPACES_RE, isBlankText, isBreakingSpace, isBreakingSpaceRun } from './spaces';
|
|
13
16
|
import { breaksAfterDash, breaksAfterHardHyphen, hasCompound, isDash, raggedStretchPx } from './breakRules';
|
|
14
17
|
/** Whether a resolved swatch colour can fill the square: a six- or
|
|
@@ -24,7 +27,7 @@ export function swatchSidePx(font) {
|
|
|
24
27
|
const size = m ? Number(m[1]) : 16;
|
|
25
28
|
return Math.max(1, size * 0.75);
|
|
26
29
|
}
|
|
27
|
-
function pickSpanFont(bold, italic, normalFont, boldFont, italicFont, boldItalicFont) {
|
|
30
|
+
export function pickSpanFont(bold, italic, normalFont, boldFont, italicFont, boldItalicFont) {
|
|
28
31
|
if (bold && italic)
|
|
29
32
|
return boldItalicFont;
|
|
30
33
|
if (bold)
|
|
@@ -92,12 +95,14 @@ export function stackedScriptPairs(scripts) {
|
|
|
92
95
|
function tokenFont(t, normalFont, boldFont, italicFont, boldItalicFont) {
|
|
93
96
|
return t.scriptFont ?? pickSpanFont(t.bold, t.italic, normalFont, boldFont, italicFont, boldItalicFont);
|
|
94
97
|
}
|
|
95
|
-
/** The script
|
|
96
|
-
* a hyphenated head) carries on. */
|
|
98
|
+
/** The script, small-caps and Chinese-mark fields a token derived from
|
|
99
|
+
* another (a split, a hyphenated head) carries on. */
|
|
97
100
|
function scriptOf(t) {
|
|
98
101
|
return {
|
|
99
102
|
...(t.script ? { script: t.script, scriptFont: t.scriptFont, baselineShift: t.baselineShift } : {}),
|
|
100
103
|
...(t.smallCaps ? { smallCaps: true } : {}),
|
|
104
|
+
...(t.cjkMarks ? { cjkMarks: t.cjkMarks } : {}),
|
|
105
|
+
...(t.inserted ? { inserted: true } : {}),
|
|
101
106
|
};
|
|
102
107
|
}
|
|
103
108
|
/** Small capitals are synthesised, the same way on every backend: a
|
|
@@ -142,8 +147,15 @@ export function smallCapsWidth(text, font) {
|
|
|
142
147
|
}
|
|
143
148
|
return w;
|
|
144
149
|
}
|
|
145
|
-
/** Advance of `text` in `font`, set in small capitals when `smallCaps`.
|
|
146
|
-
|
|
150
|
+
/** Advance of `text` in `font`, set in small capitals when `smallCaps`.
|
|
151
|
+
* In vertical text (`measuringVertically`) a character that stands in a
|
|
152
|
+
* cell of its own advances its cell (`verticalTextWidth`), as the
|
|
153
|
+
* renderers paint it, and so does a short number set in one cell
|
|
154
|
+
* (`cjk.uprightDigits`); no other ASCII text holds one. */
|
|
155
|
+
export function textWidth(text, font, smallCaps) {
|
|
156
|
+
if (measuringVertically() && (/[^\u0000-\u007F]/.test(text) || (getMeasureUprightDigits() > 0 && /[0-9]/.test(text)))) {
|
|
157
|
+
return verticalTextWidth(text, font, (run) => (smallCaps ? smallCapsWidth(run, font) : measureTextWidth(run, font)));
|
|
158
|
+
}
|
|
147
159
|
return smallCaps ? smallCapsWidth(text, font) : measureTextWidth(text, font);
|
|
148
160
|
}
|
|
149
161
|
/**
|
|
@@ -154,7 +166,7 @@ function textWidth(text, font, smallCaps) {
|
|
|
154
166
|
* line text follows the painted case (the same length, so source maps
|
|
155
167
|
* hold).
|
|
156
168
|
*/
|
|
157
|
-
function expandSmallCaps(lines, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx) {
|
|
169
|
+
export function expandSmallCaps(lines, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx) {
|
|
158
170
|
for (const line of lines) {
|
|
159
171
|
const segs = line.segments;
|
|
160
172
|
if (!segs || !segs.some((s) => s.smallCaps))
|
|
@@ -180,7 +192,7 @@ function expandSmallCaps(lines, normalFont, boldFont, italicFont, boldItalicFont
|
|
|
180
192
|
const font = run.small ? small : base;
|
|
181
193
|
const width = i === runs.length - 1
|
|
182
194
|
? seg.width - used
|
|
183
|
-
: measureTextWidth(run.text, font) + (letterSpacingPx + (line.letterSpacing ?? 0)) * run.text
|
|
195
|
+
: measureTextWidth(run.text, font) + (letterSpacingPx + (line.letterSpacing ?? 0) + (seg.tracking ?? 0)) * graphemeCount(run.text);
|
|
184
196
|
used += width;
|
|
185
197
|
// Capitals keep the segment's own font (none for a plain run).
|
|
186
198
|
const piece = { ...rest, text: run.text, width };
|
|
@@ -220,7 +232,7 @@ function withFace(font, family, sizePx) {
|
|
|
220
232
|
* enters the line height. A chip span without a resolved box sets as bare
|
|
221
233
|
* text.
|
|
222
234
|
*/
|
|
223
|
-
function chipToken(span, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx) {
|
|
235
|
+
export function chipToken(span, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx) {
|
|
224
236
|
const chip = span.chip;
|
|
225
237
|
const box = chip.box;
|
|
226
238
|
const sizeMatch = FONT_SIZE_RE.exec(normalFont);
|
|
@@ -253,7 +265,7 @@ function chipToken(span, normalFont, boldFont, italicFont, boldItalicFont, lette
|
|
|
253
265
|
runs.push({
|
|
254
266
|
text: piece.text,
|
|
255
267
|
fontString: piece.font,
|
|
256
|
-
width: measureTextWidth(piece.text, piece.font) + letterSpacingPx * piece.text
|
|
268
|
+
width: measureTextWidth(piece.text, piece.font) + letterSpacingPx * graphemeCount(piece.text),
|
|
257
269
|
...(bold ? { bold: true } : {}),
|
|
258
270
|
...(italic ? { italic: true } : {}),
|
|
259
271
|
...(baselineShift !== undefined ? { baselineShift } : {}),
|
|
@@ -380,7 +392,7 @@ function withChipMargins(token, addLeft, addRight) {
|
|
|
380
392
|
/** A word that is a URL or a bare DOI: never hyphenated by the dictionary,
|
|
381
393
|
* but breakable at its own joints so a long link cannot force an
|
|
382
394
|
* unfillable line. */
|
|
383
|
-
const URL_LIKE_RE = /^(?:(?:https?|ftp):\/\/|www\.|10\.\d{4,}\/)\S+$/i;
|
|
395
|
+
export const URL_LIKE_RE = /^(?:(?:https?|ftp):\/\/|www\.|10\.\d{4,}\/)\S+$/i;
|
|
384
396
|
/** Break opportunities inside a URL, following the usual editorial rule:
|
|
385
397
|
* after a slash (never inside the `//` of the scheme) or before a dot,
|
|
386
398
|
* hyphen or query/fragment punctuation, so the punctuation opens the next
|
|
@@ -437,10 +449,13 @@ function syllabify(word, hyphenate) {
|
|
|
437
449
|
* start of the word needs; without it, one between two letters
|
|
438
450
|
* ("largas—separadas"), for the greedy breaker only, as pretext breaks a
|
|
439
451
|
* plain paragraph there;
|
|
440
|
-
* -
|
|
441
|
-
*
|
|
442
|
-
|
|
443
|
-
|
|
452
|
+
* - next to CJK characters, under the line-break rules of the document's
|
|
453
|
+
* `cjk.lineBreak` (`cjk`: the word's units, measured once each, whose
|
|
454
|
+
* running sums give the widths before its breaks). */
|
|
455
|
+
function wordBreakPoints(clean, soft, font, letterSpacingPx, smallCaps, dashBreaks = false, touching, cjk) {
|
|
456
|
+
const widthBefore = cjk
|
|
457
|
+
? cjk.widthBefore
|
|
458
|
+
: (idx) => textWidth(clean.slice(0, idx), font, smallCaps) + (letterSpacingPx === 0 ? 0 : letterSpacingPx * graphemeCount(clean.slice(0, idx)));
|
|
444
459
|
const byIndex = new Map();
|
|
445
460
|
const add = (bp) => {
|
|
446
461
|
if (bp.charIndex <= 0 || bp.charIndex >= clean.length)
|
|
@@ -468,8 +483,9 @@ function wordBreakPoints(clean, soft, font, letterSpacingPx, smallCaps, dashBrea
|
|
|
468
483
|
}
|
|
469
484
|
for (const s of soft)
|
|
470
485
|
add(s.author ? { charIndex: s.index, author: true } : { charIndex: s.index });
|
|
471
|
-
|
|
472
|
-
|
|
486
|
+
if (cjk)
|
|
487
|
+
for (const idx of cjk.breaks)
|
|
488
|
+
add({ charIndex: idx, free: true, cjk: true });
|
|
473
489
|
return [...byIndex.values()].sort((a, b) => a.charIndex - b.charIndex);
|
|
474
490
|
}
|
|
475
491
|
/**
|
|
@@ -482,12 +498,12 @@ function wordBreakPoints(clean, soft, font, letterSpacingPx, smallCaps, dashBrea
|
|
|
482
498
|
* "-universitaria" nor "fisica--". Null when not even one character fits,
|
|
483
499
|
* or, with `syllablesOnly`, when no no-break space or syllable does.
|
|
484
500
|
*/
|
|
485
|
-
function emergencySplit(token, font, letterSpacingPx, lineMaxWidth, syllablesOnly = false) {
|
|
501
|
+
export function emergencySplit(token, font, letterSpacingPx, lineMaxWidth, syllablesOnly = false) {
|
|
486
502
|
const text = token.text;
|
|
487
503
|
if (text.length < 2)
|
|
488
504
|
return null;
|
|
489
505
|
const hyphenW = measureTextWidth('-', font) + letterSpacingPx;
|
|
490
|
-
const widthBefore = (idx) => textWidth(text.slice(0, idx), font, token.smallCaps) + letterSpacingPx * idx;
|
|
506
|
+
const widthBefore = (idx) => textWidth(text.slice(0, idx), font, token.smallCaps) + (letterSpacingPx === 0 ? 0 : letterSpacingPx * graphemeCount(text.slice(0, idx)));
|
|
491
507
|
const flags = { bold: token.bold, italic: token.italic, captionLabel: token.captionLabel, ...scriptOf(token) };
|
|
492
508
|
// A group glued by no-break spaces too wide for any line: the space is
|
|
493
509
|
// the least bad place to part it (EF-66). The line ends before it and the
|
|
@@ -508,18 +524,38 @@ function emergencySplit(token, font, letterSpacingPx, lineMaxWidth, syllablesOnl
|
|
|
508
524
|
const afterHyphen = (idx) => text[idx - 1] === '-';
|
|
509
525
|
const markW = (idx) => (afterHyphen(idx) || hasCJK(text.slice(idx - 1, idx + 1)) ? 0 : hyphenW);
|
|
510
526
|
const fits = (idx) => widthBefore(idx) + markW(idx) <= lineMaxWidth;
|
|
527
|
+
// The longest prefix that fits without its mark, found by doubling then
|
|
528
|
+
// halving (prefix widths grow with their length): no cut past it fits,
|
|
529
|
+
// so a word many lines long costs what one line of it does, not a
|
|
530
|
+
// measurement of every prefix.
|
|
531
|
+
let reach = 0;
|
|
532
|
+
let over = text.length;
|
|
533
|
+
for (let step = 1; reach + step < text.length; step *= 2) {
|
|
534
|
+
if (widthBefore(reach + step) > lineMaxWidth) {
|
|
535
|
+
over = reach + step;
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
reach += step;
|
|
539
|
+
}
|
|
540
|
+
while (over - reach > 1) {
|
|
541
|
+
const mid = (reach + over) >> 1;
|
|
542
|
+
if (widthBefore(mid) <= lineMaxWidth)
|
|
543
|
+
reach = mid;
|
|
544
|
+
else
|
|
545
|
+
over = mid;
|
|
546
|
+
}
|
|
511
547
|
let at = 0;
|
|
512
548
|
// The dictionary's syllables, as offsets into the text: `syllabify` maps
|
|
513
549
|
// them past anything else the dictionary might put in.
|
|
514
550
|
const { clean, soft } = syllabify(text, true);
|
|
515
551
|
if (clean === text) {
|
|
516
552
|
for (const s of soft) {
|
|
517
|
-
if (s.index > 0 && s.index
|
|
553
|
+
if (s.index > 0 && s.index <= reach && fits(s.index))
|
|
518
554
|
at = s.index;
|
|
519
555
|
}
|
|
520
556
|
}
|
|
521
557
|
if (at === 0 && !syllablesOnly) {
|
|
522
|
-
for (let idx =
|
|
558
|
+
for (let idx = reach; idx >= 1; idx--) {
|
|
523
559
|
// Not right before a hyphen of the text: the next line would open
|
|
524
560
|
// on it.
|
|
525
561
|
if (text[idx] === '-')
|
|
@@ -579,12 +615,135 @@ function compoundMask(spans) {
|
|
|
579
615
|
}
|
|
580
616
|
return mask;
|
|
581
617
|
}
|
|
618
|
+
/** The script fields of a span's tokens (the font at the script size, and
|
|
619
|
+
* the shift), none for text that is no superscript or subscript. */
|
|
620
|
+
export function spanScriptFields(span, normalFont, boldFont, italicFont, boldItalicFont) {
|
|
621
|
+
if (!span.script)
|
|
622
|
+
return {};
|
|
623
|
+
const base = pickSpanFont(span.bold, span.italic, normalFont, boldFont, italicFont, boldItalicFont);
|
|
624
|
+
const m = scriptMetrics(base, span.script);
|
|
625
|
+
return { script: span.script, scriptFont: m.font, baselineShift: m.baselineShift };
|
|
626
|
+
}
|
|
627
|
+
/** Whether a span sets something other than its text: a `:ref` or a
|
|
628
|
+
* note marker (its label), a chip, a swatch or a formula. The orientation
|
|
629
|
+
* marks of vertical text leave such a span as it is. */
|
|
630
|
+
export function setsObject(span) {
|
|
631
|
+
return span.ref !== undefined || span.footnote !== undefined || span.chip !== undefined || span.swatch !== undefined || span.math !== undefined || span.mathRender !== undefined;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* The one token of a span that is set as a whole, or undefined for text:
|
|
635
|
+
* - an inline `:ref` or a footnote marker: the resolved label (already in
|
|
636
|
+
* `text`) as one box that never wraps apart. Kind 'text' keeps the
|
|
637
|
+
* generic layout and renderers treating it as a word; `refResourceId` /
|
|
638
|
+
* `footnoteId` flow onto the segment for link colouring and PDF links;
|
|
639
|
+
* - a chip: a box with its own runs, never broken or hyphenated inside;
|
|
640
|
+
* - a swatch: one square the size of a capital;
|
|
641
|
+
* - a formula: one box with the render's `widthPx`. Kind 'text' (not
|
|
642
|
+
* 'space'), so trimming a line's trailing spaces never drops it.
|
|
643
|
+
*/
|
|
644
|
+
export function atomicSpanToken(span, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx) {
|
|
645
|
+
// Vertical text: a run the author set upright or sideways is one unit a
|
|
646
|
+
// line never breaks inside (tate-chu-yoko one em, upright letters one em
|
|
647
|
+
// each, a sideways run its horizontal width). A reference, a note
|
|
648
|
+
// marker, a chip, a swatch or a formula keeps its own setting.
|
|
649
|
+
if ((span.combineUpright || span.orientation) && measuringVertically() && span.text.length > 0 && !setsObject(span)) {
|
|
650
|
+
const font = pickSpanFont(span.bold, span.italic, normalFont, boldFont, italicFont, boldItalicFont);
|
|
651
|
+
const em = fontEm(font);
|
|
652
|
+
const count = span.combineUpright ? 1 : graphemeCount(span.text);
|
|
653
|
+
const track = letterSpacingPx === 0 ? 0 : letterSpacingPx * count;
|
|
654
|
+
return {
|
|
655
|
+
text: span.text,
|
|
656
|
+
bold: span.bold,
|
|
657
|
+
italic: span.italic,
|
|
658
|
+
captionLabel: span.captionLabel,
|
|
659
|
+
kind: 'text',
|
|
660
|
+
width: (span.combineUpright ? em : span.orientation === 'upright' ? em * count : measureTextWidth(span.text, font)) + track,
|
|
661
|
+
...(span.combineUpright ? { tcy: true } : { orientation: span.orientation }),
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
if (span.ref || span.footnote) {
|
|
665
|
+
const scriptFields = spanScriptFields(span, normalFont, boldFont, italicFont, boldItalicFont);
|
|
666
|
+
const refFont = scriptFields.scriptFont ?? pickSpanFont(span.bold, span.italic, normalFont, boldFont, italicFont, boldItalicFont);
|
|
667
|
+
return {
|
|
668
|
+
text: span.text,
|
|
669
|
+
bold: span.bold,
|
|
670
|
+
italic: span.italic,
|
|
671
|
+
captionLabel: span.captionLabel,
|
|
672
|
+
...scriptFields,
|
|
673
|
+
...(span.smallCaps ? { smallCaps: true } : {}),
|
|
674
|
+
kind: 'text',
|
|
675
|
+
width: textWidth(span.text, refFont, span.smallCaps) + (letterSpacingPx === 0 ? 0 : letterSpacingPx * graphemeCount(span.text)),
|
|
676
|
+
...(span.ref ? { refResourceId: span.ref.resourceId } : {}),
|
|
677
|
+
...(span.footnote ? { footnoteId: span.footnote.id } : {}),
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
if (span.chip)
|
|
681
|
+
return chipToken(span, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx);
|
|
682
|
+
if (span.swatch) {
|
|
683
|
+
const swatchFont = pickSpanFont(span.bold, span.italic, normalFont, boldFont, italicFont, boldItalicFont);
|
|
684
|
+
return {
|
|
685
|
+
text: span.text,
|
|
686
|
+
bold: span.bold,
|
|
687
|
+
italic: span.italic,
|
|
688
|
+
captionLabel: span.captionLabel,
|
|
689
|
+
kind: 'text',
|
|
690
|
+
width: swatchSidePx(swatchFont),
|
|
691
|
+
swatch: isSwatchFill(span.swatch.color) ? { color: span.swatch.color } : {},
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
if (span.math && span.mathRender) {
|
|
695
|
+
return {
|
|
696
|
+
text: span.text,
|
|
697
|
+
bold: span.bold,
|
|
698
|
+
italic: span.italic,
|
|
699
|
+
captionLabel: span.captionLabel,
|
|
700
|
+
kind: 'text',
|
|
701
|
+
width: span.mathRender.widthPx,
|
|
702
|
+
mathRender: span.mathRender,
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
return undefined;
|
|
706
|
+
}
|
|
707
|
+
/** The segment a token (or the part of one on a line) sets: its kind, text
|
|
708
|
+
* (soft hyphens removed), width and every flag the renderers read. Small
|
|
709
|
+
* capitals stay flagged until {@link expandSmallCaps} splits them. */
|
|
710
|
+
export function tokenSegment(t) {
|
|
711
|
+
const seg = {
|
|
712
|
+
kind: t.mathRender ? 'math' : t.swatch ? 'swatch' : t.chip ? 'chip' : t.kind,
|
|
713
|
+
text: cleanSoftHyphens(t.text),
|
|
714
|
+
width: t.width,
|
|
715
|
+
bold: t.bold || undefined,
|
|
716
|
+
italic: t.italic || undefined,
|
|
717
|
+
...(t.mathRender ? { mathRender: t.mathRender } : {}),
|
|
718
|
+
...(t.swatch ? { swatch: t.swatch } : {}),
|
|
719
|
+
...(t.chip ? { chip: t.chip } : {}),
|
|
720
|
+
...(t.refResourceId !== undefined ? { refResourceId: t.refResourceId } : {}),
|
|
721
|
+
...(t.footnoteId !== undefined ? { footnoteId: t.footnoteId } : {}),
|
|
722
|
+
...(t.captionLabel ? { captionLabel: true } : {}),
|
|
723
|
+
...(t.script ? { script: t.script, fontString: t.scriptFont, baselineShift: t.baselineShift } : {}),
|
|
724
|
+
...(t.stacked === 'first' ? { stacked: true } : {}),
|
|
725
|
+
...(t.smallCaps ? { smallCaps: true } : {}),
|
|
726
|
+
};
|
|
727
|
+
// The fields of vertical and Chinese text, last, when set.
|
|
728
|
+
if (t.tcy)
|
|
729
|
+
seg.tcy = true;
|
|
730
|
+
if (t.orientation)
|
|
731
|
+
seg.orientation = t.orientation;
|
|
732
|
+
if (t.cjkMarks)
|
|
733
|
+
seg.cjkMarks = t.cjkMarks;
|
|
734
|
+
if (t.inserted)
|
|
735
|
+
seg.inserted = true;
|
|
736
|
+
return seg;
|
|
737
|
+
}
|
|
582
738
|
function tokenizeSpans(spans, normalFont, boldFont, italicFont, boldItalicFont, shouldHyphenate, letterSpacingPx = 0,
|
|
583
739
|
/** `MeasureBlockOptions.breakAfterDashes`. */
|
|
584
740
|
dashBreaks = false,
|
|
585
741
|
/** `MeasureBlockOptions.hyphenateCompounds === false`: the dictionary
|
|
586
742
|
* leaves the words of a compound whole. */
|
|
587
|
-
keepCompounds = false
|
|
743
|
+
keepCompounds = false,
|
|
744
|
+
/** Whether the spans hold CJK characters (`hasCJK` of their text): only
|
|
745
|
+
* then is each word looked into. */
|
|
746
|
+
cjkText = true) {
|
|
588
747
|
const tokens = [];
|
|
589
748
|
// Which characters of the joined text sit in a compound, a word (across
|
|
590
749
|
// runs: "*after*-dinner") with a hyphen between two letters.
|
|
@@ -593,7 +752,7 @@ keepCompounds = false) {
|
|
|
593
752
|
// Tracking: every character (spaces included) advances `letterSpacingPx`
|
|
594
753
|
// more, exactly as canvas `letterSpacing` / CSS `letter-spacing` / PDF `Tc`
|
|
595
754
|
// paint it, so measured widths stay in step with the renderers.
|
|
596
|
-
const track = (text) => letterSpacingPx * text
|
|
755
|
+
const track = (text) => (letterSpacingPx === 0 ? 0 : letterSpacingPx * graphemeCount(text));
|
|
597
756
|
/** The script fields of a span's tokens (font at the script size, shift). */
|
|
598
757
|
const scriptFieldsOf = (span) => {
|
|
599
758
|
if (!span.script)
|
|
@@ -606,62 +765,19 @@ keepCompounds = false) {
|
|
|
606
765
|
for (const span of spans) {
|
|
607
766
|
const spanBase = spanStart;
|
|
608
767
|
spanStart += span.text.length;
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
// onto the segment for link colouring / PDF link annotations.
|
|
613
|
-
if (span.ref || span.footnote) {
|
|
614
|
-
const refFont = spanFont(span);
|
|
615
|
-
tokens.push({
|
|
616
|
-
text: span.text,
|
|
617
|
-
bold: span.bold,
|
|
618
|
-
italic: span.italic,
|
|
619
|
-
captionLabel: span.captionLabel,
|
|
620
|
-
...scriptFieldsOf(span),
|
|
621
|
-
...(span.smallCaps ? { smallCaps: true } : {}),
|
|
622
|
-
kind: 'text',
|
|
623
|
-
width: textWidth(span.text, refFont, span.smallCaps) + track(span.text),
|
|
624
|
-
...(span.ref ? { refResourceId: span.ref.resourceId } : {}),
|
|
625
|
-
...(span.footnote ? { footnoteId: span.footnote.id } : {}),
|
|
626
|
-
});
|
|
627
|
-
continue;
|
|
628
|
-
}
|
|
629
|
-
// Chips are atomic boxes: never broken or hyphenated inside.
|
|
630
|
-
if (span.chip) {
|
|
631
|
-
tokens.push(chipToken(span, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx));
|
|
632
|
-
continue;
|
|
633
|
-
}
|
|
634
|
-
// Swatch spans are atomic too: one square box the size of a capital.
|
|
635
|
-
if (span.swatch) {
|
|
636
|
-
const swatchFont = pickSpanFont(span.bold, span.italic, normalFont, boldFont, italicFont, boldItalicFont);
|
|
637
|
-
tokens.push({
|
|
638
|
-
text: span.text,
|
|
639
|
-
bold: span.bold,
|
|
640
|
-
italic: span.italic,
|
|
641
|
-
captionLabel: span.captionLabel,
|
|
642
|
-
kind: 'text',
|
|
643
|
-
width: swatchSidePx(swatchFont),
|
|
644
|
-
swatch: isSwatchFill(span.swatch.color) ? { color: span.swatch.color } : {},
|
|
645
|
-
});
|
|
646
|
-
continue;
|
|
647
|
-
}
|
|
648
|
-
// Math spans are atomic: a single non-breaking box with the render's
|
|
649
|
-
// widthPx. Kind 'text' is correct (not 'space') so trimming trailing
|
|
650
|
-
// spaces from a line doesn't drop the formula.
|
|
651
|
-
if (span.math && span.mathRender) {
|
|
652
|
-
tokens.push({
|
|
653
|
-
text: span.text,
|
|
654
|
-
bold: span.bold,
|
|
655
|
-
italic: span.italic,
|
|
656
|
-
captionLabel: span.captionLabel,
|
|
657
|
-
kind: 'text',
|
|
658
|
-
width: span.mathRender.widthPx,
|
|
659
|
-
mathRender: span.mathRender,
|
|
660
|
-
});
|
|
768
|
+
const atomic = atomicSpanToken(span, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx);
|
|
769
|
+
if (atomic) {
|
|
770
|
+
tokens.push(atomic);
|
|
661
771
|
continue;
|
|
662
772
|
}
|
|
663
773
|
const font = spanFont(span);
|
|
664
|
-
|
|
774
|
+
// Chinese marks (#193) ride on the span's words like its script.
|
|
775
|
+
const marks = spanMarks(span, getMeasureWritingMode() === 'vertical-rl');
|
|
776
|
+
const scriptFields = {
|
|
777
|
+
...scriptFieldsOf(span),
|
|
778
|
+
...(marks ? { cjkMarks: marks } : {}),
|
|
779
|
+
...(span.inserted ? { inserted: true } : {}),
|
|
780
|
+
};
|
|
665
781
|
// Small capitals: the words keep their case (hyphenation reads it) and
|
|
666
782
|
// measure as they will be painted.
|
|
667
783
|
const sc = !!span.smallCaps;
|
|
@@ -683,7 +799,7 @@ keepCompounds = false) {
|
|
|
683
799
|
const clean = part.replace(/\u00AD/g, '');
|
|
684
800
|
const breakPoints = urlBreakIndices(clean).map((charIndex) => ({
|
|
685
801
|
charIndex,
|
|
686
|
-
widthBefore: textWidth(clean.slice(0, charIndex), font, sc) + letterSpacingPx * charIndex,
|
|
802
|
+
widthBefore: textWidth(clean.slice(0, charIndex), font, sc) + (letterSpacingPx === 0 ? 0 : letterSpacingPx * graphemeCount(clean.slice(0, charIndex))),
|
|
687
803
|
}));
|
|
688
804
|
tokens.push({
|
|
689
805
|
text: clean,
|
|
@@ -706,7 +822,9 @@ keepCompounds = false) {
|
|
|
706
822
|
const touching = dashBreaks && before && before.kind === 'text' && !before.mathRender && !before.swatch && !before.chip
|
|
707
823
|
? before.text.slice(-2)
|
|
708
824
|
: undefined;
|
|
709
|
-
|
|
825
|
+
// A word that holds CJK characters: measured unit by unit, once each.
|
|
826
|
+
const cjk = cjkText && !isSpace && hasCJK(clean) ? cjkWordBreaks(clean, font, sc, letterSpacingPx) : undefined;
|
|
827
|
+
const breakPoints = isSpace ? [] : wordBreakPoints(clean, soft, font, letterSpacingPx, sc, dashBreaks, touching, cjk);
|
|
710
828
|
if (breakPoints.length > 0) {
|
|
711
829
|
tokens.push({
|
|
712
830
|
text: clean,
|
|
@@ -716,7 +834,7 @@ keepCompounds = false) {
|
|
|
716
834
|
...scriptFields,
|
|
717
835
|
...scFields,
|
|
718
836
|
kind: 'text',
|
|
719
|
-
width: textWidth(clean, font, sc) + track(clean),
|
|
837
|
+
width: cjk ? cjk.width : textWidth(clean, font, sc) + track(clean),
|
|
720
838
|
breakPoints,
|
|
721
839
|
hyphenWidth: measureTextWidth('-', font) + letterSpacingPx,
|
|
722
840
|
});
|
|
@@ -738,7 +856,7 @@ keepCompounds = false) {
|
|
|
738
856
|
if (tokens.some((t) => t.script))
|
|
739
857
|
stackScriptTokens(tokens, normalFont, boldFont, italicFont, boldItalicFont);
|
|
740
858
|
if (tokens.some((t) => t.chip)) {
|
|
741
|
-
applyChipGaps(tokens, (t, run) => measureTextWidth(run, tokenFont(t, normalFont, boldFont, italicFont, boldItalicFont)) + letterSpacingPx * run
|
|
859
|
+
applyChipGaps(tokens, (t, run) => measureTextWidth(run, tokenFont(t, normalFont, boldFont, italicFont, boldItalicFont)) + (letterSpacingPx === 0 ? 0 : letterSpacingPx * graphemeCount(run)));
|
|
742
860
|
}
|
|
743
861
|
if (dashBreaks)
|
|
744
862
|
markDashJoins(tokens);
|
|
@@ -927,27 +1045,45 @@ export function measureRichSnippet(spans, normalFont, boldFont, italicFont, bold
|
|
|
927
1045
|
return measureRichText(spans, plainText, normalFont, boldFont, italicFont, boldItalicFont, maxWidthPx, lineHeightPx, options);
|
|
928
1046
|
}
|
|
929
1047
|
function measureRichText(spans, plainText, normalFont, boldFont, italicFont, boldItalicFont, maxWidthPx, lineHeightPx, options) {
|
|
1048
|
+
// A writing mode asked for this text alone (`options.writingMode`): every
|
|
1049
|
+
// width below reads it.
|
|
1050
|
+
if (options?.writingMode !== undefined && options.writingMode !== getMeasureWritingMode()) {
|
|
1051
|
+
const opts = options;
|
|
1052
|
+
return withMeasureWritingMode(opts.writingMode, () => measureRichText(spans, plainText, normalFont, boldFont, italicFont, boldItalicFont, maxWidthPx, lineHeightPx, opts));
|
|
1053
|
+
}
|
|
1054
|
+
// Chinese, Japanese or Korean text: its own composer, which breaks
|
|
1055
|
+
// between characters under the document's line-break rules and spreads
|
|
1056
|
+
// justified lines between them — also text with no two CJK letters in a
|
|
1057
|
+
// row (价¥5,999。好, 第1条、第2条). A Latin paragraph that only quotes a
|
|
1058
|
+
// few CJK words stays here, with a break allowed next to their characters.
|
|
1059
|
+
// So is a paragraph with ruby or a warichu note (#194, #195), which the
|
|
1060
|
+
// composer alone lays out.
|
|
1061
|
+
// The paragraph is looked at for CJK text once (`cjkText`); a Latin one
|
|
1062
|
+
// then never looks into its words.
|
|
1063
|
+
const cjkText = hasCJK(plainText);
|
|
1064
|
+
if ((cjkText && composesAsCjk(plainText)) || spans.some((s) => s.ruby || s.warichu)) {
|
|
1065
|
+
return composeCjkParagraph(spans, normalFont, boldFont, italicFont, boldItalicFont, maxWidthPx, lineHeightPx, options);
|
|
1066
|
+
}
|
|
930
1067
|
const shouldHyphenate = options?.hyphenate ?? false;
|
|
931
1068
|
const indentPx = options?.firstLineIndentPx ?? 0;
|
|
932
1069
|
const hanging = options?.hangingIndent ?? false;
|
|
933
1070
|
const textAlign = options?.textAlign ?? 'left';
|
|
934
1071
|
const letterSpacingPx = options?.letterSpacingPx ?? 0;
|
|
935
1072
|
const hyphenationZonePx = shouldHyphenate ? options?.hyphenationZonePx : undefined;
|
|
936
|
-
const tokens = tokenizeSpans(spans, normalFont, boldFont, italicFont, boldItalicFont, shouldHyphenate, letterSpacingPx, options?.breakAfterDashes === true, options?.hyphenateCompounds === false);
|
|
1073
|
+
const tokens = tokenizeSpans(spans, normalFont, boldFont, italicFont, boldItalicFont, shouldHyphenate, letterSpacingPx, options?.breakAfterDashes === true, options?.hyphenateCompounds === false, cjkText);
|
|
937
1074
|
const repeatHyphen = options?.repeatHyphen === true;
|
|
938
1075
|
const hasSmallCaps = tokens.some((t) => t.smallCaps);
|
|
939
1076
|
const normalSpaceWidth = textAlign === 'justify' ? normalSpaceWidthFor(normalFont) + letterSpacingPx : 0;
|
|
940
1077
|
if (tokens.length === 0) {
|
|
941
1078
|
return { lines: [], totalHeight: 0 };
|
|
942
1079
|
}
|
|
943
|
-
// Knuth-Plass optimal line breaking path.
|
|
944
|
-
//
|
|
945
|
-
//
|
|
946
|
-
//
|
|
947
|
-
//
|
|
948
|
-
// their width and each line gets the ragged stretch instead.
|
|
1080
|
+
// Knuth-Plass optimal line breaking path. A Latin paragraph quoting CJK
|
|
1081
|
+
// words takes it too: the breaks next to their characters are free
|
|
1082
|
+
// penalties, as a hyphenation point that adds nothing. Ragged text takes
|
|
1083
|
+
// it too with `optimalRagged`: its word spaces keep their width and each
|
|
1084
|
+
// line gets the ragged stretch instead.
|
|
949
1085
|
const ragged = textAlign !== 'justify';
|
|
950
|
-
if (options?.optimal && (!ragged || options.optimalRagged)
|
|
1086
|
+
if (options?.optimal && (!ragged || options.optimalRagged)) {
|
|
951
1087
|
const maxStretchRatio = ragged ? 1 : options.maxStretchRatio ?? 1.5;
|
|
952
1088
|
const minShrinkRatio = ragged ? 1 : options.minShrinkRatio ?? 0.8;
|
|
953
1089
|
// The runt threshold counts word spaces on ragged text too.
|
|
@@ -988,7 +1124,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
988
1124
|
...(ragged && hyphenationZonePx !== undefined ? { hyphenationZone: hyphenationZonePx } : {}),
|
|
989
1125
|
});
|
|
990
1126
|
if (breaks.length > 0) {
|
|
991
|
-
const kpLines = reconstructRichLines(items, breaks, tokens, lineHeightPx, lineWidthFn, lineIndentFn, normalSpaceWidth, textAlign, trackingPerChar);
|
|
1127
|
+
const kpLines = reconstructRichLines(items, breaks, tokens, lineHeightPx, lineWidthFn, lineIndentFn, normalSpaceWidth, textAlign, trackingPerChar, lineBaselineOffset(lineHeightPx, normalFont));
|
|
992
1128
|
if (!hasOverfullLine(kpLines, lineWidthFn, ragged)) {
|
|
993
1129
|
if (hasSmallCaps)
|
|
994
1130
|
expandSmallCaps(kpLines, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx);
|
|
@@ -1004,6 +1140,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1004
1140
|
// measure (a word wider than it: the greedy breaker divides it)
|
|
1005
1141
|
}
|
|
1006
1142
|
const lines = [];
|
|
1143
|
+
const baselineOffset = lineBaselineOffset(lineHeightPx, normalFont);
|
|
1007
1144
|
let y = 0;
|
|
1008
1145
|
let tokenIdx = 0;
|
|
1009
1146
|
let lineIndex = 0;
|
|
@@ -1076,7 +1213,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1076
1213
|
const split = splitToken(token, chosen, mark, markW(chosen));
|
|
1077
1214
|
lineTokens.push(split.head);
|
|
1078
1215
|
lineWidth += split.head.width;
|
|
1079
|
-
lineHyphenated = true;
|
|
1216
|
+
lineHyphenated = chosen.cjk !== true;
|
|
1080
1217
|
lineSyllable = mark !== '' && !chosen.author;
|
|
1081
1218
|
lineHardHyphen = chosen.bare === true;
|
|
1082
1219
|
lineRepeatNext = repeatHyphen && chosen.bare === true && !token.bareBreaks;
|
|
@@ -1106,9 +1243,9 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1106
1243
|
if (glued > 0) {
|
|
1107
1244
|
const prev = lineTokens[lineTokens.length - 1];
|
|
1108
1245
|
const font = tokenFont(token, normalFont, boldFont, italicFont, boldItalicFont);
|
|
1109
|
-
if (token.stacked !== 'second' && cjkJoinBreaks(prev.text, token.text
|
|
1110
|
-
// The line ends
|
|
1111
|
-
|
|
1246
|
+
if (token.stacked !== 'second' && token.footnoteId === undefined && token.refResourceId === undefined && cjkJoinBreaks(prev.text, token.text)) {
|
|
1247
|
+
// The line ends between two runs, next to a CJK character: no
|
|
1248
|
+
// space is consumed and nothing is added.
|
|
1112
1249
|
break;
|
|
1113
1250
|
}
|
|
1114
1251
|
// The group's latest plain break (between ideographs, a dash, a
|
|
@@ -1133,7 +1270,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1133
1270
|
lineWidth += split.head.width;
|
|
1134
1271
|
tokens[origIdx] = split.tail;
|
|
1135
1272
|
tokenIdx = origIdx;
|
|
1136
|
-
lineHyphenated = true;
|
|
1273
|
+
lineHyphenated = back.bp.cjk !== true;
|
|
1137
1274
|
lineHardHyphen = back.bp.bare === true;
|
|
1138
1275
|
lineRepeatNext = repeatHyphen && back.bp.bare === true && !back.token.bareBreaks;
|
|
1139
1276
|
break;
|
|
@@ -1217,29 +1354,14 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1217
1354
|
}
|
|
1218
1355
|
const isLastLine = peekIdx >= tokens.length;
|
|
1219
1356
|
// Build segments for justified rendering
|
|
1220
|
-
const segments = trimChipLineEdges(lineTokens.map(
|
|
1221
|
-
kind: t.mathRender ? 'math' : t.swatch ? 'swatch' : t.chip ? 'chip' : t.kind,
|
|
1222
|
-
text: cleanSoftHyphens(t.text),
|
|
1223
|
-
width: t.width,
|
|
1224
|
-
bold: t.bold || undefined,
|
|
1225
|
-
italic: t.italic || undefined,
|
|
1226
|
-
...(t.mathRender ? { mathRender: t.mathRender } : {}),
|
|
1227
|
-
...(t.swatch ? { swatch: t.swatch } : {}),
|
|
1228
|
-
...(t.chip ? { chip: t.chip } : {}),
|
|
1229
|
-
...(t.refResourceId !== undefined ? { refResourceId: t.refResourceId } : {}),
|
|
1230
|
-
...(t.footnoteId !== undefined ? { footnoteId: t.footnoteId } : {}),
|
|
1231
|
-
...(t.captionLabel ? { captionLabel: true } : {}),
|
|
1232
|
-
...(t.script ? { script: t.script, fontString: t.scriptFont, baselineShift: t.baselineShift } : {}),
|
|
1233
|
-
...(t.stacked === 'first' ? { stacked: true } : {}),
|
|
1234
|
-
...(t.smallCaps ? { smallCaps: true } : {}),
|
|
1235
|
-
})));
|
|
1357
|
+
const segments = trimChipLineEdges(lineTokens.map(tokenSegment));
|
|
1236
1358
|
const lineText = lineTokens.map((t) => cleanSoftHyphens(t.text)).join('');
|
|
1237
1359
|
const contentWidth = segments.reduce((sum, t) => sum + t.width, 0);
|
|
1238
1360
|
const justifiedSpaceRatio = computeJustifiedSpaceRatio(segments, lineMaxWidth, normalSpaceWidth, textAlign, isLastLine);
|
|
1239
1361
|
lines.push({
|
|
1240
1362
|
text: lineText,
|
|
1241
1363
|
bbox: createBoundingBox(lineIndent, y, contentWidth, lineHeightPx),
|
|
1242
|
-
baseline: y +
|
|
1364
|
+
baseline: y + baselineOffset,
|
|
1243
1365
|
hyphenated: lineHyphenated,
|
|
1244
1366
|
...(lineHyphenated && lineHardHyphen ? { hardHyphen: true } : {}),
|
|
1245
1367
|
...(lineRepeated && lineText.startsWith('-') ? { repeatedHyphen: true } : {}),
|