shape-text 0.1.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/LICENSE +21 -0
- package/README.md +264 -0
- package/dist/geometry/get-band-intervals-from-polygon.d.ts +2 -0
- package/dist/geometry/get-band-intervals-from-polygon.js +44 -0
- package/dist/geometry/get-band-intervals-from-polygon.js.map +1 -0
- package/dist/geometry/get-polygon-bounds.d.ts +2 -0
- package/dist/geometry/get-polygon-bounds.js +18 -0
- package/dist/geometry/get-polygon-bounds.js.map +1 -0
- package/dist/geometry/get-x-intersections-at-y.d.ts +2 -0
- package/dist/geometry/get-x-intersections-at-y.js +15 -0
- package/dist/geometry/get-x-intersections-at-y.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/layout-dense-fill-pass.d.ts +23 -0
- package/dist/layout/layout-dense-fill-pass.js +64 -0
- package/dist/layout/layout-dense-fill-pass.js.map +1 -0
- package/dist/layout/layout-flow-lines-in-compiled-shape.d.ts +13 -0
- package/dist/layout/layout-flow-lines-in-compiled-shape.js +42 -0
- package/dist/layout/layout-flow-lines-in-compiled-shape.js.map +1 -0
- package/dist/layout/layout-text-in-compiled-shape.d.ts +2 -0
- package/dist/layout/layout-text-in-compiled-shape.js +13 -0
- package/dist/layout/layout-text-in-compiled-shape.js.map +1 -0
- package/dist/layout/layout-text-in-shape.d.ts +2 -0
- package/dist/layout/layout-text-in-shape.js +40 -0
- package/dist/layout/layout-text-in-shape.js.map +1 -0
- package/dist/layout/resolve-flow-layout.d.ts +2 -0
- package/dist/layout/resolve-flow-layout.js +31 -0
- package/dist/layout/resolve-flow-layout.js.map +1 -0
- package/dist/layout/resolve-max-fill-helpers.d.ts +3 -0
- package/dist/layout/resolve-max-fill-helpers.js +18 -0
- package/dist/layout/resolve-max-fill-helpers.js.map +1 -0
- package/dist/layout/resolve-max-fill-layout.d.ts +2 -0
- package/dist/layout/resolve-max-fill-layout.js +34 -0
- package/dist/layout/resolve-max-fill-layout.js.map +1 -0
- package/dist/layout/resolve-sequential-shape-regions.d.ts +3 -0
- package/dist/layout/resolve-sequential-shape-regions.js +95 -0
- package/dist/layout/resolve-sequential-shape-regions.js.map +1 -0
- package/dist/render/escape-xml-text.d.ts +1 -0
- package/dist/render/escape-xml-text.js +9 -0
- package/dist/render/escape-xml-text.js.map +1 -0
- package/dist/render/normalize-shape-decoration.d.ts +2 -0
- package/dist/render/normalize-shape-decoration.js +41 -0
- package/dist/render/normalize-shape-decoration.js.map +1 -0
- package/dist/render/render-layout-to-svg.d.ts +2 -0
- package/dist/render/render-layout-to-svg.js +88 -0
- package/dist/render/render-layout-to-svg.js.map +1 -0
- package/dist/render/render-svg-shadow-filter.d.ts +10 -0
- package/dist/render/render-svg-shadow-filter.js +16 -0
- package/dist/render/render-svg-shadow-filter.js.map +1 -0
- package/dist/shape/build-text-mask-bands-from-alpha.d.ts +8 -0
- package/dist/shape/build-text-mask-bands-from-alpha.js +73 -0
- package/dist/shape/build-text-mask-bands-from-alpha.js.map +1 -0
- package/dist/shape/compile-polygon-shape-for-layout.d.ts +2 -0
- package/dist/shape/compile-polygon-shape-for-layout.js +26 -0
- package/dist/shape/compile-polygon-shape-for-layout.js.map +1 -0
- package/dist/shape/compile-shape-for-layout.d.ts +2 -0
- package/dist/shape/compile-shape-for-layout.js +18 -0
- package/dist/shape/compile-shape-for-layout.js.map +1 -0
- package/dist/shape/compile-text-mask-shape-for-layout.d.ts +2 -0
- package/dist/shape/compile-text-mask-shape-for-layout.js +162 -0
- package/dist/shape/compile-text-mask-shape-for-layout.js.map +1 -0
- package/dist/shape/render-text-mask-raster.d.ts +13 -0
- package/dist/shape/render-text-mask-raster.js +29 -0
- package/dist/shape/render-text-mask-raster.js.map +1 -0
- package/dist/shape/resolve-text-mask-shape-size.d.ts +18 -0
- package/dist/shape/resolve-text-mask-shape-size.js +67 -0
- package/dist/shape/resolve-text-mask-shape-size.js.map +1 -0
- package/dist/shape/segment-text-mask-graphemes.d.ts +6 -0
- package/dist/shape/segment-text-mask-graphemes.js +20 -0
- package/dist/shape/segment-text-mask-graphemes.js.map +1 -0
- package/dist/text/create-browser-canvas-2d-context.d.ts +2 -0
- package/dist/text/create-browser-canvas-2d-context.js +21 -0
- package/dist/text/create-browser-canvas-2d-context.js.map +1 -0
- package/dist/text/create-canvas-text-measurer.d.ts +2 -0
- package/dist/text/create-canvas-text-measurer.js +11 -0
- package/dist/text/create-canvas-text-measurer.js.map +1 -0
- package/dist/text/layout-next-line-from-dense-repeated-text.d.ts +2 -0
- package/dist/text/layout-next-line-from-dense-repeated-text.js +63 -0
- package/dist/text/layout-next-line-from-dense-repeated-text.js.map +1 -0
- package/dist/text/layout-next-line-from-prepared-text.d.ts +2 -0
- package/dist/text/layout-next-line-from-prepared-text.js +57 -0
- package/dist/text/layout-next-line-from-prepared-text.js.map +1 -0
- package/dist/text/layout-next-line-from-repeated-text.d.ts +2 -0
- package/dist/text/layout-next-line-from-repeated-text.js +51 -0
- package/dist/text/layout-next-line-from-repeated-text.js.map +1 -0
- package/dist/text/layout-text-line-helpers.d.ts +4 -0
- package/dist/text/layout-text-line-helpers.js +17 -0
- package/dist/text/layout-text-line-helpers.js.map +1 -0
- package/dist/text/normalize-text-style-to-font.d.ts +6 -0
- package/dist/text/normalize-text-style-to-font.js +31 -0
- package/dist/text/normalize-text-style-to-font.js.map +1 -0
- package/dist/text/prepare-dense-repeat-fill-pattern.d.ts +2 -0
- package/dist/text/prepare-dense-repeat-fill-pattern.js +13 -0
- package/dist/text/prepare-dense-repeat-fill-pattern.js.map +1 -0
- package/dist/text/prepare-stream-repeat-fill-pattern.d.ts +2 -0
- package/dist/text/prepare-stream-repeat-fill-pattern.js +16 -0
- package/dist/text/prepare-stream-repeat-fill-pattern.js.map +1 -0
- package/dist/text/prepare-text-for-layout.d.ts +2 -0
- package/dist/text/prepare-text-for-layout.js +22 -0
- package/dist/text/prepare-text-for-layout.js.map +1 -0
- package/dist/text/segment-text-for-layout.d.ts +3 -0
- package/dist/text/segment-text-for-layout.js +43 -0
- package/dist/text/segment-text-for-layout.js.map +1 -0
- package/dist/types.d.ts +200 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { resolveLayoutTextStyle } from '../text/normalize-text-style-to-font.js';
|
|
2
|
+
import { prepareTextForLayout } from '../text/prepare-text-for-layout.js';
|
|
3
|
+
import { layoutFlowLinesInCompiledShape } from './layout-flow-lines-in-compiled-shape.js';
|
|
4
|
+
export function resolveFlowLayout(options) {
|
|
5
|
+
const resolvedTextStyle = resolveLayoutTextStyle({
|
|
6
|
+
font: options.font,
|
|
7
|
+
textStyle: options.textStyle,
|
|
8
|
+
});
|
|
9
|
+
const align = options.align ?? 'left';
|
|
10
|
+
const baselineRatio = options.baselineRatio ?? 0.8;
|
|
11
|
+
const prepared = prepareTextForLayout(options.text, resolvedTextStyle.font, options.measurer);
|
|
12
|
+
const { lines, endCursor } = layoutFlowLinesInCompiledShape({
|
|
13
|
+
compiledShape: options.compiledShape,
|
|
14
|
+
prepared,
|
|
15
|
+
align,
|
|
16
|
+
baselineRatio,
|
|
17
|
+
startCursor: { tokenIndex: 0, graphemeIndex: 0 },
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
font: resolvedTextStyle.font,
|
|
21
|
+
textStyle: resolvedTextStyle,
|
|
22
|
+
lineHeight: options.compiledShape.bandHeight,
|
|
23
|
+
shape: options.compiledShape.source,
|
|
24
|
+
compiledShape: options.compiledShape,
|
|
25
|
+
bounds: options.compiledShape.bounds,
|
|
26
|
+
lines,
|
|
27
|
+
exhausted: endCursor.tokenIndex >= prepared.tokens.length,
|
|
28
|
+
autoFill: false,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=resolve-flow-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-flow-layout.js","sourceRoot":"","sources":["../../src/layout/resolve-flow-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAA;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AACzE,OAAO,EAAE,8BAA8B,EAAE,MAAM,0CAA0C,CAAA;AAEzF,MAAM,UAAU,iBAAiB,CAC/B,OAAyC;IAEzC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;QAC/C,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAAA;IACrC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,GAAG,CAAA;IAClD,MAAM,QAAQ,GAAG,oBAAoB,CACnC,OAAO,CAAC,IAAI,EACZ,iBAAiB,CAAC,IAAI,EACtB,OAAO,CAAC,QAAQ,CACjB,CAAA;IACD,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,8BAA8B,CAAC;QAC1D,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,QAAQ;QACR,KAAK;QACL,aAAa;QACb,WAAW,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;KACjD,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,EAAE,iBAAiB,CAAC,IAAI;QAC5B,SAAS,EAAE,iBAAiB;QAC5B,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,UAAU;QAC5C,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,MAAM;QACnC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,MAAM;QACpC,KAAK;QACL,SAAS,EAAE,SAAS,CAAC,UAAU,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM;QACzD,QAAQ,EAAE,KAAK;KAChB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { compileShapeForLayout } from '../shape/compile-shape-for-layout.js';
|
|
2
|
+
const MAX_FILL_BASE_MIN_SLOT_WIDTH_FACTOR = 0.45;
|
|
3
|
+
const MIN_MAX_FILL_SLOT_WIDTH = 6;
|
|
4
|
+
export function resolveMaxFillMinSlotWidth(lineHeight) {
|
|
5
|
+
return Math.max(MIN_MAX_FILL_SLOT_WIDTH, Math.round(lineHeight * MAX_FILL_BASE_MIN_SLOT_WIDTH_FACTOR));
|
|
6
|
+
}
|
|
7
|
+
export function ensureMaxFillCompiledShape(compiledShape) {
|
|
8
|
+
const recommendedMinSlotWidth = resolveMaxFillMinSlotWidth(compiledShape.bandHeight);
|
|
9
|
+
if (compiledShape.minSlotWidth <= recommendedMinSlotWidth) {
|
|
10
|
+
return compiledShape;
|
|
11
|
+
}
|
|
12
|
+
return compileShapeForLayout({
|
|
13
|
+
shape: compiledShape.source,
|
|
14
|
+
lineHeight: compiledShape.bandHeight,
|
|
15
|
+
minSlotWidth: recommendedMinSlotWidth,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=resolve-max-fill-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-max-fill-helpers.js","sourceRoot":"","sources":["../../src/layout/resolve-max-fill-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAA;AAE5E,MAAM,mCAAmC,GAAG,IAAI,CAAA;AAChD,MAAM,uBAAuB,GAAG,CAAC,CAAA;AAEjC,MAAM,UAAU,0BAA0B,CAAC,UAAkB;IAC3D,OAAO,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,mCAAmC,CAAC,CAAC,CAAA;AACxG,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,aAAiC;IAC1E,MAAM,uBAAuB,GAAG,0BAA0B,CAAC,aAAa,CAAC,UAAU,CAAC,CAAA;IACpF,IAAI,aAAa,CAAC,YAAY,IAAI,uBAAuB,EAAE,CAAC;QAC1D,OAAO,aAAa,CAAA;IACtB,CAAC;IAED,OAAO,qBAAqB,CAAC;QAC3B,KAAK,EAAE,aAAa,CAAC,MAAM;QAC3B,UAAU,EAAE,aAAa,CAAC,UAAU;QACpC,YAAY,EAAE,uBAAuB;KACtC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { resolveLayoutTextStyle } from '../text/normalize-text-style-to-font.js';
|
|
2
|
+
import { prepareStreamRepeatFillPattern } from '../text/prepare-stream-repeat-fill-pattern.js';
|
|
3
|
+
import { layoutDenseFillPass } from './layout-dense-fill-pass.js';
|
|
4
|
+
import { ensureMaxFillCompiledShape } from './resolve-max-fill-helpers.js';
|
|
5
|
+
export function resolveMaxFillLayout(options) {
|
|
6
|
+
const resolvedTextStyle = resolveLayoutTextStyle({
|
|
7
|
+
font: options.font,
|
|
8
|
+
textStyle: options.textStyle,
|
|
9
|
+
});
|
|
10
|
+
const baselineRatio = options.baselineRatio ?? 0.8;
|
|
11
|
+
const maxCompiledShape = ensureMaxFillCompiledShape(options.compiledShape);
|
|
12
|
+
const streamPattern = prepareStreamRepeatFillPattern(options.text, resolvedTextStyle.font, options.measurer);
|
|
13
|
+
const pass = layoutDenseFillPass({
|
|
14
|
+
compiledShape: maxCompiledShape,
|
|
15
|
+
densePattern: streamPattern,
|
|
16
|
+
startOffset: 0,
|
|
17
|
+
align: 'left',
|
|
18
|
+
baselineRatio,
|
|
19
|
+
allSlots: true,
|
|
20
|
+
fillPass: 1,
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
font: resolvedTextStyle.font,
|
|
24
|
+
textStyle: resolvedTextStyle,
|
|
25
|
+
lineHeight: maxCompiledShape.bandHeight,
|
|
26
|
+
shape: maxCompiledShape.source,
|
|
27
|
+
compiledShape: maxCompiledShape,
|
|
28
|
+
bounds: maxCompiledShape.bounds,
|
|
29
|
+
lines: pass.lines,
|
|
30
|
+
exhausted: false,
|
|
31
|
+
autoFill: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=resolve-max-fill-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-max-fill-layout.js","sourceRoot":"","sources":["../../src/layout/resolve-max-fill-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAA;AAChF,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAA;AAC9F,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAE1E,MAAM,UAAU,oBAAoB,CAClC,OAAyC;IAEzC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;QAC/C,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAA;IACF,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,GAAG,CAAA;IAClD,MAAM,gBAAgB,GAAG,0BAA0B,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;IAC1E,MAAM,aAAa,GAAG,8BAA8B,CAClD,OAAO,CAAC,IAAI,EACZ,iBAAiB,CAAC,IAAI,EACtB,OAAO,CAAC,QAAQ,CACjB,CAAA;IAED,MAAM,IAAI,GAAG,mBAAmB,CAAC;QAC/B,aAAa,EAAE,gBAAgB;QAC/B,YAAY,EAAE,aAAa;QAC3B,WAAW,EAAE,CAAC;QACd,KAAK,EAAE,MAAM;QACb,aAAa;QACb,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,CAAC;KACZ,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,EAAE,iBAAiB,CAAC,IAAI;QAC5B,SAAS,EAAE,iBAAiB;QAC5B,UAAU,EAAE,gBAAgB,CAAC,UAAU;QACvC,KAAK,EAAE,gBAAgB,CAAC,MAAM;QAC9B,aAAa,EAAE,gBAAgB;QAC/B,MAAM,EAAE,gBAAgB,CAAC,MAAM;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,IAAI;KACf,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CompiledShapeBands, LayoutTextInCompiledShapeOptions, ShapeTextLayout } from '../types.js';
|
|
2
|
+
export declare function hasSequentialShapeRegions(compiledShape: CompiledShapeBands): boolean;
|
|
3
|
+
export declare function resolveSequentialShapeRegions(options: LayoutTextInCompiledShapeOptions): ShapeTextLayout;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { resolveLayoutTextStyle } from '../text/normalize-text-style-to-font.js';
|
|
2
|
+
import { prepareStreamRepeatFillPattern } from '../text/prepare-stream-repeat-fill-pattern.js';
|
|
3
|
+
import { prepareTextForLayout } from '../text/prepare-text-for-layout.js';
|
|
4
|
+
import { layoutDenseFillPass } from './layout-dense-fill-pass.js';
|
|
5
|
+
import { layoutFlowLinesInCompiledShape } from './layout-flow-lines-in-compiled-shape.js';
|
|
6
|
+
import { ensureMaxFillCompiledShape } from './resolve-max-fill-helpers.js';
|
|
7
|
+
function createCompiledShapeFromRegion(compiledShape, region) {
|
|
8
|
+
return {
|
|
9
|
+
kind: compiledShape.kind,
|
|
10
|
+
source: compiledShape.source,
|
|
11
|
+
bounds: region.bounds,
|
|
12
|
+
bandHeight: compiledShape.bandHeight,
|
|
13
|
+
minSlotWidth: compiledShape.minSlotWidth,
|
|
14
|
+
bands: region.bands,
|
|
15
|
+
debugView: region.debugView,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function hasSequentialShapeRegions(compiledShape) {
|
|
19
|
+
return (compiledShape.source.kind === 'text-mask' &&
|
|
20
|
+
(compiledShape.source.shapeTextMode ?? 'whole-text') === 'per-character' &&
|
|
21
|
+
(compiledShape.regions?.some(region => region.bands.some(band => band.intervals.length > 0)) ?? false));
|
|
22
|
+
}
|
|
23
|
+
export function resolveSequentialShapeRegions(options) {
|
|
24
|
+
const autoFill = options.autoFill ?? false;
|
|
25
|
+
const resolvedTextStyle = resolveLayoutTextStyle({
|
|
26
|
+
font: options.font,
|
|
27
|
+
textStyle: options.textStyle,
|
|
28
|
+
});
|
|
29
|
+
const align = options.align ?? 'left';
|
|
30
|
+
const baselineRatio = options.baselineRatio ?? 0.8;
|
|
31
|
+
const compiledShape = autoFill
|
|
32
|
+
? ensureMaxFillCompiledShape(options.compiledShape)
|
|
33
|
+
: options.compiledShape;
|
|
34
|
+
const regions = compiledShape.regions ?? [];
|
|
35
|
+
if (autoFill) {
|
|
36
|
+
const streamPattern = prepareStreamRepeatFillPattern(options.text, resolvedTextStyle.font, options.measurer);
|
|
37
|
+
const lines = [];
|
|
38
|
+
let offset = 0;
|
|
39
|
+
for (let index = 0; index < regions.length; index++) {
|
|
40
|
+
const regionShape = createCompiledShapeFromRegion(compiledShape, regions[index]);
|
|
41
|
+
const pass = layoutDenseFillPass({
|
|
42
|
+
compiledShape: regionShape,
|
|
43
|
+
densePattern: streamPattern,
|
|
44
|
+
startOffset: offset,
|
|
45
|
+
align: 'left',
|
|
46
|
+
baselineRatio,
|
|
47
|
+
allSlots: true,
|
|
48
|
+
fillPass: 1,
|
|
49
|
+
});
|
|
50
|
+
lines.push(...pass.lines);
|
|
51
|
+
offset = pass.endOffset;
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
font: resolvedTextStyle.font,
|
|
55
|
+
textStyle: resolvedTextStyle,
|
|
56
|
+
lineHeight: compiledShape.bandHeight,
|
|
57
|
+
shape: compiledShape.source,
|
|
58
|
+
compiledShape,
|
|
59
|
+
bounds: compiledShape.bounds,
|
|
60
|
+
lines,
|
|
61
|
+
exhausted: false,
|
|
62
|
+
autoFill: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const prepared = prepareTextForLayout(options.text, resolvedTextStyle.font, options.measurer);
|
|
66
|
+
const lines = [];
|
|
67
|
+
let cursor = { tokenIndex: 0, graphemeIndex: 0 };
|
|
68
|
+
for (let index = 0; index < regions.length; index++) {
|
|
69
|
+
const regionShape = createCompiledShapeFromRegion(compiledShape, regions[index]);
|
|
70
|
+
const result = layoutFlowLinesInCompiledShape({
|
|
71
|
+
compiledShape: regionShape,
|
|
72
|
+
prepared,
|
|
73
|
+
align,
|
|
74
|
+
baselineRatio,
|
|
75
|
+
startCursor: cursor,
|
|
76
|
+
});
|
|
77
|
+
lines.push(...result.lines);
|
|
78
|
+
cursor = result.endCursor;
|
|
79
|
+
if (!autoFill && prepared !== undefined && cursor.tokenIndex >= prepared.tokens.length) {
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
font: resolvedTextStyle.font,
|
|
85
|
+
textStyle: resolvedTextStyle,
|
|
86
|
+
lineHeight: compiledShape.bandHeight,
|
|
87
|
+
shape: compiledShape.source,
|
|
88
|
+
compiledShape,
|
|
89
|
+
bounds: compiledShape.bounds,
|
|
90
|
+
lines,
|
|
91
|
+
exhausted: cursor.tokenIndex >= prepared.tokens.length,
|
|
92
|
+
autoFill: false,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=resolve-sequential-shape-regions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-sequential-shape-regions.js","sourceRoot":"","sources":["../../src/layout/resolve-sequential-shape-regions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function escapeXmlText(value: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape-xml-text.js","sourceRoot":"","sources":["../../src/render/escape-xml-text.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK;SACT,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;AAC9B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
function assertFiniteNonNegative(value, message) {
|
|
2
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
3
|
+
throw new Error(message);
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
function normalizeShadow(shadow) {
|
|
7
|
+
if (shadow === undefined) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
assertFiniteNonNegative(shadow.blur, 'shapeStyle.shadow.blur must be a finite non-negative number');
|
|
11
|
+
const offsetX = shadow.offsetX ?? 0;
|
|
12
|
+
const offsetY = shadow.offsetY ?? 0;
|
|
13
|
+
if (!Number.isFinite(offsetX) || !Number.isFinite(offsetY)) {
|
|
14
|
+
throw new Error('shapeStyle.shadow offsets must be finite numbers');
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
color: shadow.color ?? 'rgba(15, 23, 42, 0.24)',
|
|
18
|
+
blur: shadow.blur,
|
|
19
|
+
offsetX,
|
|
20
|
+
offsetY,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function normalizeShapeDecoration(options) {
|
|
24
|
+
const explicitBorderWidth = options.shapeStyle?.borderWidth;
|
|
25
|
+
if (explicitBorderWidth !== undefined) {
|
|
26
|
+
assertFiniteNonNegative(explicitBorderWidth, 'shapeStyle.borderWidth must be a finite non-negative number');
|
|
27
|
+
}
|
|
28
|
+
const borderWidth = explicitBorderWidth ??
|
|
29
|
+
(options.shapeStyle?.borderColor !== undefined
|
|
30
|
+
? 1
|
|
31
|
+
: options.shapeStyle === undefined && (options.shapeStroke !== undefined || options.showShape === true)
|
|
32
|
+
? 1
|
|
33
|
+
: 0);
|
|
34
|
+
return {
|
|
35
|
+
backgroundColor: options.shapeStyle?.backgroundColor ?? options.shapeFill,
|
|
36
|
+
borderColor: options.shapeStyle?.borderColor ?? options.shapeStroke ?? '#d1d5db',
|
|
37
|
+
borderWidth,
|
|
38
|
+
shadow: normalizeShadow(options.shapeStyle?.shadow),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=normalize-shape-decoration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-shape-decoration.js","sourceRoot":"","sources":["../../src/render/normalize-shape-decoration.ts"],"names":[],"mappings":"AAMA,SAAS,uBAAuB,CAAC,KAAa,EAAE,OAAe;IAC7D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,MAAoC;IAC3D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,uBAAuB,CAAC,MAAM,CAAC,IAAI,EAAE,6DAA6D,CAAC,CAAA;IAEnG,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,CAAA;IACnC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,CAAA;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IACrE,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,wBAAwB;QAC/C,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO;QACP,OAAO;KACR,CAAA;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,OAAiC;IAEjC,MAAM,mBAAmB,GAAG,OAAO,CAAC,UAAU,EAAE,WAAW,CAAA;IAC3D,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACtC,uBAAuB,CACrB,mBAAmB,EACnB,6DAA6D,CAC9D,CAAA;IACH,CAAC;IAED,MAAM,WAAW,GACf,mBAAmB;QACnB,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,KAAK,SAAS;YAC5C,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC;gBACrG,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,CAAC,CAAC,CAAA;IAEV,OAAO;QACL,eAAe,EAAE,OAAO,CAAC,UAAU,EAAE,eAAe,IAAI,OAAO,CAAC,SAAS;QACzE,WAAW,EAAE,OAAO,CAAC,UAAU,EAAE,WAAW,IAAI,OAAO,CAAC,WAAW,IAAI,SAAS;QAChF,WAAW;QACX,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC;KACpD,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createSvgShadowFilter } from './render-svg-shadow-filter.js';
|
|
2
|
+
import { normalizeShapeDecoration } from './normalize-shape-decoration.js';
|
|
3
|
+
import { escapeXmlText } from './escape-xml-text.js';
|
|
4
|
+
function renderPoints(points) {
|
|
5
|
+
return points.map(point => `${point.x},${point.y}`).join(' ');
|
|
6
|
+
}
|
|
7
|
+
function getEffectPadding(options) {
|
|
8
|
+
const strokePadding = options.strokeWidth / 2;
|
|
9
|
+
const shadowBlurPadding = options.shadow === undefined ? 0 : options.shadow.blur * 3;
|
|
10
|
+
return {
|
|
11
|
+
left: strokePadding +
|
|
12
|
+
(options.shadow === undefined ? 0 : shadowBlurPadding + Math.max(0, -options.shadow.offsetX)),
|
|
13
|
+
right: strokePadding +
|
|
14
|
+
(options.shadow === undefined ? 0 : shadowBlurPadding + Math.max(0, options.shadow.offsetX)),
|
|
15
|
+
top: strokePadding +
|
|
16
|
+
(options.shadow === undefined ? 0 : shadowBlurPadding + Math.max(0, -options.shadow.offsetY)),
|
|
17
|
+
bottom: strokePadding +
|
|
18
|
+
(options.shadow === undefined ? 0 : shadowBlurPadding + Math.max(0, options.shadow.offsetY)),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function renderShapeAttributes(debugView, options) {
|
|
22
|
+
const filter = options.filterUrl === undefined ? '' : ` filter="${options.filterUrl}"`;
|
|
23
|
+
const fill = escapeXmlText(options.fill);
|
|
24
|
+
const stroke = escapeXmlText(options.stroke);
|
|
25
|
+
if (debugView.kind === 'polygon') {
|
|
26
|
+
return `<polygon points="${renderPoints(debugView.points)}" fill="${fill}" stroke="${stroke}" stroke-width="${options.strokeWidth}"${filter} />`;
|
|
27
|
+
}
|
|
28
|
+
return `<text x="${debugView.x}" y="${debugView.baseline}" fill="${fill}" stroke="${stroke}" stroke-width="${options.strokeWidth}"${filter} style="font:${escapeXmlText(debugView.font)};">${escapeXmlText(debugView.text)}</text>`;
|
|
29
|
+
}
|
|
30
|
+
export function renderLayoutToSvg(layout, options = {}) {
|
|
31
|
+
const userPadding = options.padding ?? 0;
|
|
32
|
+
const textFill = options.textFill ?? layout.textStyle?.color ?? '#111827';
|
|
33
|
+
const shapeStyle = normalizeShapeDecoration(options);
|
|
34
|
+
const background = options.background;
|
|
35
|
+
const hasVisibleCanonicalShapeDecoration = options.shapeStyle !== undefined &&
|
|
36
|
+
(shapeStyle.backgroundColor !== undefined ||
|
|
37
|
+
shapeStyle.borderWidth > 0 ||
|
|
38
|
+
shapeStyle.shadow !== undefined);
|
|
39
|
+
const showShape = options.showShape ?? hasVisibleCanonicalShapeDecoration;
|
|
40
|
+
const effectPadding = showShape
|
|
41
|
+
? getEffectPadding({
|
|
42
|
+
strokeWidth: shapeStyle.borderWidth,
|
|
43
|
+
shadow: shapeStyle.shadow,
|
|
44
|
+
})
|
|
45
|
+
: { left: 0, right: 0, top: 0, bottom: 0 };
|
|
46
|
+
const totalPadding = {
|
|
47
|
+
left: userPadding + effectPadding.left,
|
|
48
|
+
right: userPadding + effectPadding.right,
|
|
49
|
+
top: userPadding + effectPadding.top,
|
|
50
|
+
bottom: userPadding + effectPadding.bottom,
|
|
51
|
+
};
|
|
52
|
+
const width = layout.bounds.right - layout.bounds.left + totalPadding.left + totalPadding.right;
|
|
53
|
+
const height = layout.bounds.bottom - layout.bounds.top + totalPadding.top + totalPadding.bottom;
|
|
54
|
+
const viewBoxLeft = layout.bounds.left - totalPadding.left;
|
|
55
|
+
const viewBoxTop = layout.bounds.top - totalPadding.top;
|
|
56
|
+
const shadowFilter = showShape && shapeStyle.shadow !== undefined
|
|
57
|
+
? createSvgShadowFilter(shapeStyle.shadow, {
|
|
58
|
+
x: viewBoxLeft,
|
|
59
|
+
y: viewBoxTop,
|
|
60
|
+
width,
|
|
61
|
+
height,
|
|
62
|
+
})
|
|
63
|
+
: undefined;
|
|
64
|
+
const pieces = [
|
|
65
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBoxLeft} ${viewBoxTop} ${width} ${height}" width="${width}" height="${height}">`,
|
|
66
|
+
];
|
|
67
|
+
if (shadowFilter !== undefined) {
|
|
68
|
+
pieces.push(shadowFilter.markup);
|
|
69
|
+
}
|
|
70
|
+
if (background !== undefined) {
|
|
71
|
+
pieces.push(`<rect x="${viewBoxLeft}" y="${viewBoxTop}" width="${width}" height="${height}" fill="${escapeXmlText(background)}" />`);
|
|
72
|
+
}
|
|
73
|
+
if (showShape) {
|
|
74
|
+
pieces.push(renderShapeAttributes(layout.compiledShape.debugView, {
|
|
75
|
+
fill: shapeStyle.backgroundColor ?? 'none',
|
|
76
|
+
stroke: shapeStyle.borderColor,
|
|
77
|
+
strokeWidth: shapeStyle.borderWidth,
|
|
78
|
+
filterUrl: shadowFilter === undefined ? undefined : `url(#${shadowFilter.filterId})`,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
for (let index = 0; index < layout.lines.length; index++) {
|
|
82
|
+
const line = layout.lines[index];
|
|
83
|
+
pieces.push(`<text x="${line.x}" y="${line.baseline}" fill="${escapeXmlText(textFill)}" style="font:${escapeXmlText(line.font ?? layout.font)};">${escapeXmlText(line.text)}</text>`);
|
|
84
|
+
}
|
|
85
|
+
pieces.push('</svg>');
|
|
86
|
+
return pieces.join('');
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=render-layout-to-svg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-layout-to-svg.js","sourceRoot":"","sources":["../../src/render/render-layout-to-svg.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ResolvedShapeShadow } from '../types.js';
|
|
2
|
+
export declare function createSvgShadowFilter(shadow: ResolvedShapeShadow, filterRegion: {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}): {
|
|
8
|
+
filterId: string;
|
|
9
|
+
markup: string;
|
|
10
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { escapeXmlText } from './escape-xml-text.js';
|
|
2
|
+
function hashString(value) {
|
|
3
|
+
let hash = 0;
|
|
4
|
+
for (let index = 0; index < value.length; index++) {
|
|
5
|
+
hash = (hash * 31 + value.charCodeAt(index)) >>> 0;
|
|
6
|
+
}
|
|
7
|
+
return hash.toString(36);
|
|
8
|
+
}
|
|
9
|
+
export function createSvgShadowFilter(shadow, filterRegion) {
|
|
10
|
+
const filterId = `shape-text-shape-shadow-${hashString(JSON.stringify(shadow))}`;
|
|
11
|
+
return {
|
|
12
|
+
filterId,
|
|
13
|
+
markup: `<defs><filter id="${filterId}" filterUnits="userSpaceOnUse" x="${filterRegion.x}" y="${filterRegion.y}" width="${filterRegion.width}" height="${filterRegion.height}"><feDropShadow dx="${shadow.offsetX}" dy="${shadow.offsetY}" stdDeviation="${shadow.blur}" flood-color="${escapeXmlText(shadow.color)}" /></filter></defs>`,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=render-svg-shadow-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-svg-shadow-filter.js","sourceRoot":"","sources":["../../src/render/render-svg-shadow-filter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEpD,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,IAAI,GAAG,CAAC,CAAA;IAEZ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,IAAI,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAA;IACpD,CAAC;IAED,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;AAC1B,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,MAA2B,EAC3B,YAKC;IAKD,MAAM,QAAQ,GAAG,2BAA2B,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAA;IAEhF,OAAO;QACL,QAAQ;QACR,MAAM,EAAE,qBAAqB,QAAQ,qCAAqC,YAAY,CAAC,CAAC,QAAQ,YAAY,CAAC,CAAC,YAAY,YAAY,CAAC,KAAK,aAAa,YAAY,CAAC,MAAM,uBAAuB,MAAM,CAAC,OAAO,SAAS,MAAM,CAAC,OAAO,mBAAmB,MAAM,CAAC,IAAI,kBAAkB,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB;KAC1U,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CompiledShapeBand } from '../types.js';
|
|
2
|
+
export type TextMaskAlphaBandsOptions = {
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
maskScale: number;
|
|
6
|
+
alphaThreshold: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function buildTextMaskBandsFromAlpha(options: TextMaskAlphaBandsOptions, alpha: Uint8ClampedArray, lineHeight: number, minSlotWidth: number): CompiledShapeBand[];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
function intersectIntervalSets(leftSet, rightSet) {
|
|
2
|
+
const intersections = [];
|
|
3
|
+
let leftIndex = 0;
|
|
4
|
+
let rightIndex = 0;
|
|
5
|
+
while (leftIndex < leftSet.length && rightIndex < rightSet.length) {
|
|
6
|
+
const left = leftSet[leftIndex];
|
|
7
|
+
const right = rightSet[rightIndex];
|
|
8
|
+
const overlapLeft = Math.max(left.left, right.left);
|
|
9
|
+
const overlapRight = Math.min(left.right, right.right);
|
|
10
|
+
if (overlapRight > overlapLeft) {
|
|
11
|
+
intersections.push({ left: overlapLeft, right: overlapRight });
|
|
12
|
+
}
|
|
13
|
+
if (left.right < right.right) {
|
|
14
|
+
leftIndex += 1;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
rightIndex += 1;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return intersections;
|
|
21
|
+
}
|
|
22
|
+
function getRowIntervals(alpha, row, width, alphaThreshold) {
|
|
23
|
+
const intervals = [];
|
|
24
|
+
let start = -1;
|
|
25
|
+
const rowOffset = row * width * 4;
|
|
26
|
+
for (let x = 0; x < width; x++) {
|
|
27
|
+
const isSolid = alpha[rowOffset + x * 4 + 3] >= alphaThreshold;
|
|
28
|
+
if (isSolid && start < 0) {
|
|
29
|
+
start = x;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (!isSolid && start >= 0) {
|
|
33
|
+
intervals.push({ left: start, right: x });
|
|
34
|
+
start = -1;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (start >= 0) {
|
|
38
|
+
intervals.push({ left: start, right: width });
|
|
39
|
+
}
|
|
40
|
+
return intervals;
|
|
41
|
+
}
|
|
42
|
+
export function buildTextMaskBandsFromAlpha(options, alpha, lineHeight, minSlotWidth) {
|
|
43
|
+
const pixelWidth = Math.max(1, Math.ceil(options.width * options.maskScale));
|
|
44
|
+
const bands = [];
|
|
45
|
+
for (let bandTop = 0; bandTop + lineHeight <= options.height; bandTop += lineHeight) {
|
|
46
|
+
const startRow = Math.floor(bandTop * options.maskScale);
|
|
47
|
+
const endRow = Math.max(startRow, Math.ceil((bandTop + lineHeight) * options.maskScale) - 1);
|
|
48
|
+
let intervals = null;
|
|
49
|
+
for (let row = startRow; row <= endRow; row++) {
|
|
50
|
+
const rowIntervals = getRowIntervals(alpha, row, pixelWidth, options.alphaThreshold);
|
|
51
|
+
if (rowIntervals.length === 0) {
|
|
52
|
+
intervals = [];
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
intervals = intervals === null ? rowIntervals : intersectIntervalSets(intervals, rowIntervals);
|
|
56
|
+
if (intervals.length === 0) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
bands.push({
|
|
61
|
+
top: bandTop,
|
|
62
|
+
bottom: bandTop + lineHeight,
|
|
63
|
+
intervals: (intervals ?? [])
|
|
64
|
+
.map(interval => ({
|
|
65
|
+
left: interval.left / options.maskScale,
|
|
66
|
+
right: interval.right / options.maskScale,
|
|
67
|
+
}))
|
|
68
|
+
.filter(interval => interval.right - interval.left >= minSlotWidth),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return bands;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=build-text-mask-bands-from-alpha.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-text-mask-bands-from-alpha.js","sourceRoot":"","sources":["../../src/shape/build-text-mask-bands-from-alpha.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getBandIntervalsFromPolygon } from '../geometry/get-band-intervals-from-polygon.js';
|
|
2
|
+
import { getPolygonBounds } from '../geometry/get-polygon-bounds.js';
|
|
3
|
+
export function compilePolygonShapeForLayout(shape, lineHeight, minSlotWidth) {
|
|
4
|
+
const bounds = getPolygonBounds(shape.points);
|
|
5
|
+
const bands = [];
|
|
6
|
+
for (let bandTop = bounds.top; bandTop + lineHeight <= bounds.bottom; bandTop += lineHeight) {
|
|
7
|
+
bands.push({
|
|
8
|
+
top: bandTop,
|
|
9
|
+
bottom: bandTop + lineHeight,
|
|
10
|
+
intervals: getBandIntervalsFromPolygon(shape.points, bandTop, bandTop + lineHeight, minSlotWidth),
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
kind: shape.kind,
|
|
15
|
+
source: shape,
|
|
16
|
+
bounds,
|
|
17
|
+
bandHeight: lineHeight,
|
|
18
|
+
minSlotWidth,
|
|
19
|
+
bands,
|
|
20
|
+
debugView: {
|
|
21
|
+
kind: 'polygon',
|
|
22
|
+
points: shape.points,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=compile-polygon-shape-for-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-polygon-shape-for-layout.js","sourceRoot":"","sources":["../../src/shape/compile-polygon-shape-for-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAA;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AAEpE,MAAM,UAAU,4BAA4B,CAC1C,KAAmB,EACnB,UAAkB,EAClB,YAAoB;IAEpB,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7C,MAAM,KAAK,GAAG,EAAE,CAAA;IAEhB,KAAK,IAAI,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,UAAU,EAAE,CAAC;QAC5F,KAAK,CAAC,IAAI,CAAC;YACT,GAAG,EAAE,OAAO;YACZ,MAAM,EAAE,OAAO,GAAG,UAAU;YAC5B,SAAS,EAAE,2BAA2B,CACpC,KAAK,CAAC,MAAM,EACZ,OAAO,EACP,OAAO,GAAG,UAAU,EACpB,YAAY,CACb;SACF,CAAC,CAAA;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK;QACb,MAAM;QACN,UAAU,EAAE,UAAU;QACtB,YAAY;QACZ,KAAK;QACL,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { compilePolygonShapeForLayout } from './compile-polygon-shape-for-layout.js';
|
|
2
|
+
import { compileTextMaskShapeForLayout } from './compile-text-mask-shape-for-layout.js';
|
|
3
|
+
export function compileShapeForLayout(options) {
|
|
4
|
+
if (!Number.isFinite(options.lineHeight) || options.lineHeight <= 0) {
|
|
5
|
+
throw new Error('lineHeight must be a finite positive number');
|
|
6
|
+
}
|
|
7
|
+
const minSlotWidth = options.minSlotWidth ?? Math.max(16, options.lineHeight * 0.8);
|
|
8
|
+
if (!Number.isFinite(minSlotWidth) || minSlotWidth < 0) {
|
|
9
|
+
throw new Error('minSlotWidth must be a finite non-negative number');
|
|
10
|
+
}
|
|
11
|
+
switch (options.shape.kind) {
|
|
12
|
+
case 'polygon':
|
|
13
|
+
return compilePolygonShapeForLayout(options.shape, options.lineHeight, minSlotWidth);
|
|
14
|
+
case 'text-mask':
|
|
15
|
+
return compileTextMaskShapeForLayout(options.shape, options.lineHeight, minSlotWidth);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=compile-shape-for-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-shape-for-layout.js","sourceRoot":"","sources":["../../src/shape/compile-shape-for-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAA;AACpF,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAA;AAEvF,MAAM,UAAU,qBAAqB,CACnC,OAAqC;IAErC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAChE,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC,CAAA;IACnF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACtE,CAAC;IAED,QAAQ,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC3B,KAAK,SAAS;YACZ,OAAO,4BAA4B,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;QAEtF,KAAK,WAAW;YACd,OAAO,6BAA6B,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IACzF,CAAC;AACH,CAAC"}
|