fabricjs-document-engine 1.2.0 → 1.3.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/README.md +31 -0
- package/README.zh-CN.md +32 -0
- package/dist/commands/text-edit.cjs +223 -0
- package/dist/commands/text-edit.d.cts +23 -0
- package/dist/commands/text-edit.d.ts +23 -0
- package/dist/commands/text-edit.js +218 -0
- package/dist/fabric/object-registry.cjs +7 -1
- package/dist/fabric/object-registry.js +7 -1
- package/dist/filters/filter-worker.cjs +281 -0
- package/dist/filters/filter-worker.d.cts +26 -0
- package/dist/filters/filter-worker.d.ts +26 -0
- package/dist/filters/filter-worker.js +281 -0
- package/dist/filters/pipeline.cjs +91 -0
- package/dist/filters/pipeline.d.cts +35 -0
- package/dist/filters/pipeline.d.ts +35 -0
- package/dist/filters/pipeline.js +87 -0
- package/dist/filters/worker-entry.cjs +78 -0
- package/dist/filters/worker-entry.d.cts +29 -0
- package/dist/filters/worker-entry.d.ts +29 -0
- package/dist/filters/worker-entry.js +78 -0
- package/dist/filters.cjs +9 -0
- package/dist/filters.d.cts +3 -0
- package/dist/filters.d.ts +3 -0
- package/dist/filters.js +3 -0
- package/dist/import/svg-import.cjs +102 -0
- package/dist/import/svg-import.d.cts +1 -0
- package/dist/import/svg-import.d.ts +1 -0
- package/dist/import/svg-import.js +103 -1
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/performance/batch.cjs +31 -0
- package/dist/performance/batch.d.cts +4 -0
- package/dist/performance/batch.d.ts +4 -0
- package/dist/performance/batch.js +31 -0
- package/dist/performance/dirty-regions.cjs +378 -0
- package/dist/performance/dirty-regions.d.cts +23 -0
- package/dist/performance/dirty-regions.d.ts +23 -0
- package/dist/performance/dirty-regions.js +378 -0
- package/dist/performance/monitor.cjs +60 -0
- package/dist/performance/monitor.d.cts +20 -0
- package/dist/performance/monitor.d.ts +20 -0
- package/dist/performance/monitor.js +60 -0
- package/dist/performance/spatial-index.cjs +78 -0
- package/dist/performance/spatial-index.d.cts +21 -0
- package/dist/performance/spatial-index.d.ts +21 -0
- package/dist/performance/spatial-index.js +78 -0
- package/dist/performance.cjs +9 -0
- package/dist/performance.d.cts +5 -0
- package/dist/performance.d.ts +5 -0
- package/dist/performance.js +5 -0
- package/dist/text/bounded-textbox.cjs +306 -0
- package/dist/text/bounded-textbox.d.cts +53 -0
- package/dist/text/bounded-textbox.d.ts +53 -0
- package/dist/text/bounded-textbox.js +306 -0
- package/dist/text/mobile-input.cjs +146 -0
- package/dist/text/mobile-input.d.cts +19 -0
- package/dist/text/mobile-input.d.ts +19 -0
- package/dist/text/mobile-input.js +145 -0
- package/dist/text/register.cjs +17 -0
- package/dist/text/register.d.cts +5 -0
- package/dist/text/register.d.ts +5 -0
- package/dist/text/register.js +16 -0
- package/dist/text/shaping.cjs +125 -0
- package/dist/text/shaping.d.cts +28 -0
- package/dist/text/shaping.d.ts +28 -0
- package/dist/text/shaping.js +121 -0
- package/dist/text/vertical-orientation.cjs +192 -0
- package/dist/text/vertical-orientation.d.cts +10 -0
- package/dist/text/vertical-orientation.d.ts +10 -0
- package/dist/text/vertical-orientation.js +190 -0
- package/dist/text/vertical-text.cjs +336 -0
- package/dist/text/vertical-text.d.cts +54 -0
- package/dist/text/vertical-text.d.ts +54 -0
- package/dist/text/vertical-text.js +336 -0
- package/dist/text.cjs +21 -0
- package/dist/text.d.cts +7 -0
- package/dist/text.d.ts +7 -0
- package/dist/text.js +7 -0
- package/package.json +31 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
let fabric = require("fabric");
|
|
2
|
+
//#region src/text/shaping.ts
|
|
3
|
+
const CACHE_LIMIT = 4096;
|
|
4
|
+
const widths = /* @__PURE__ */ new Map();
|
|
5
|
+
let measuringContext;
|
|
6
|
+
function context() {
|
|
7
|
+
measuringContext ?? (measuringContext = fabric.util.createCanvasElement().getContext("2d"));
|
|
8
|
+
return measuringContext;
|
|
9
|
+
}
|
|
10
|
+
function measure(ctx, font, text) {
|
|
11
|
+
if (text === "") return 0;
|
|
12
|
+
const key = `${font}\u0000${text}`;
|
|
13
|
+
const known = widths.get(key);
|
|
14
|
+
if (known !== void 0) {
|
|
15
|
+
widths.delete(key);
|
|
16
|
+
widths.set(key, known);
|
|
17
|
+
return known;
|
|
18
|
+
}
|
|
19
|
+
const width = ctx.measureText(text).width;
|
|
20
|
+
widths.set(key, width);
|
|
21
|
+
if (widths.size > CACHE_LIMIT) widths.delete(widths.keys().next().value);
|
|
22
|
+
return width;
|
|
23
|
+
}
|
|
24
|
+
function drawsJoinedRuns(text) {
|
|
25
|
+
const self = text;
|
|
26
|
+
return !self.path && self.charSpacing === 0 && !self.textAlign.includes("justify");
|
|
27
|
+
}
|
|
28
|
+
const isSpace = (grapheme) => /\s/.test(grapheme);
|
|
29
|
+
function runLefts(ctx, font, graphemes, start, end, scale) {
|
|
30
|
+
const lefts = new Array(end - start + 1);
|
|
31
|
+
let segmentStart = start;
|
|
32
|
+
let segmentLeft = 0;
|
|
33
|
+
for (let index = start; index < end; index += 1) {
|
|
34
|
+
if (index > start && isSpace(graphemes[index]) !== isSpace(graphemes[index - 1])) {
|
|
35
|
+
segmentStart = index;
|
|
36
|
+
segmentLeft = measure(ctx, font, graphemes.slice(start, index).join(""));
|
|
37
|
+
}
|
|
38
|
+
lefts[index - start] = (segmentLeft + measure(ctx, font, graphemes.slice(segmentStart, index).join(""))) * scale;
|
|
39
|
+
}
|
|
40
|
+
lefts[end - start] = measure(ctx, font, graphemes.slice(start, end).join("")) * scale;
|
|
41
|
+
return lefts;
|
|
42
|
+
}
|
|
43
|
+
function styleRuns(text, lineIndex, length) {
|
|
44
|
+
const self = text;
|
|
45
|
+
const runs = [];
|
|
46
|
+
let start = 0;
|
|
47
|
+
let style = self.getCompleteStyleDeclaration(lineIndex, 0);
|
|
48
|
+
for (let index = 1; index <= length; index += 1) {
|
|
49
|
+
const next = index < length ? self.getCompleteStyleDeclaration(lineIndex, index) : void 0;
|
|
50
|
+
if (!next || fabric.util.hasStyleChanged(style, next, false)) {
|
|
51
|
+
runs.push([
|
|
52
|
+
start,
|
|
53
|
+
index,
|
|
54
|
+
style
|
|
55
|
+
]);
|
|
56
|
+
start = index;
|
|
57
|
+
if (next) style = next;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return runs;
|
|
61
|
+
}
|
|
62
|
+
function shapeLine(text, lineIndex, measured) {
|
|
63
|
+
if (!drawsJoinedRuns(text)) return measured;
|
|
64
|
+
const self = text;
|
|
65
|
+
const graphemes = self._textLines[lineIndex] ?? [];
|
|
66
|
+
const bounds = self.__charBounds[lineIndex];
|
|
67
|
+
if (!bounds || graphemes.length === 0) return measured;
|
|
68
|
+
const ctx = context();
|
|
69
|
+
let runLeft = 0;
|
|
70
|
+
for (const [start, end, style] of styleRuns(text, lineIndex, graphemes.length)) {
|
|
71
|
+
self._setTextStyles(ctx, style, true);
|
|
72
|
+
const lefts = runLefts(ctx, ctx.font, graphemes, start, end, style.fontSize / self.CACHE_FONT_SIZE);
|
|
73
|
+
for (let index = start; index < end; index += 1) {
|
|
74
|
+
const box = bounds[index];
|
|
75
|
+
box.left = runLeft + lefts[index - start];
|
|
76
|
+
box.width = box.kernedWidth = lefts[index - start + 1] - lefts[index - start];
|
|
77
|
+
}
|
|
78
|
+
runLeft += lefts[end - start];
|
|
79
|
+
}
|
|
80
|
+
const last = bounds[graphemes.length];
|
|
81
|
+
if (last) last.left = runLeft;
|
|
82
|
+
return {
|
|
83
|
+
width: runLeft,
|
|
84
|
+
numOfSpaces: measured.numOfSpaces
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function shapeWord(text, word, lineIndex, charOffset, fallback) {
|
|
88
|
+
if (!drawsJoinedRuns(text) || word.length === 0) return fallback;
|
|
89
|
+
const self = text;
|
|
90
|
+
const ctx = context();
|
|
91
|
+
let width = 0;
|
|
92
|
+
let start = 0;
|
|
93
|
+
let style = self.getCompleteStyleDeclaration(lineIndex, charOffset);
|
|
94
|
+
for (let index = 1; index <= word.length; index += 1) {
|
|
95
|
+
const next = index < word.length ? self.getCompleteStyleDeclaration(lineIndex, charOffset + index) : void 0;
|
|
96
|
+
if (!next || fabric.util.hasStyleChanged(style, next, false)) {
|
|
97
|
+
self._setTextStyles(ctx, style, true);
|
|
98
|
+
width += measure(ctx, ctx.font, word.slice(start, index).join("")) * style.fontSize / self.CACHE_FONT_SIZE;
|
|
99
|
+
start = index;
|
|
100
|
+
if (next) style = next;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return width;
|
|
104
|
+
}
|
|
105
|
+
var ShapedIText = class extends fabric.IText {
|
|
106
|
+
_measureLine(lineIndex) {
|
|
107
|
+
return shapeLine(this, lineIndex, super._measureLine(lineIndex));
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
ShapedIText.type = "ShapedIText";
|
|
111
|
+
var ShapedTextbox = class extends fabric.Textbox {
|
|
112
|
+
_measureLine(lineIndex) {
|
|
113
|
+
return shapeLine(this, lineIndex, super._measureLine(lineIndex));
|
|
114
|
+
}
|
|
115
|
+
_measureWord(word, lineIndex, charOffset = 0) {
|
|
116
|
+
return shapeWord(this, word, lineIndex, charOffset, super._measureWord(word, lineIndex, charOffset));
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
ShapedTextbox.type = "ShapedTextbox";
|
|
120
|
+
//#endregion
|
|
121
|
+
exports.ShapedIText = ShapedIText;
|
|
122
|
+
exports.ShapedTextbox = ShapedTextbox;
|
|
123
|
+
exports.drawsJoinedRuns = drawsJoinedRuns;
|
|
124
|
+
exports.shapeLine = shapeLine;
|
|
125
|
+
exports.shapeWord = shapeWord;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IText, Textbox } from "fabric";
|
|
2
|
+
//#region src/text/shaping.d.ts
|
|
3
|
+
export type AnyText = object;
|
|
4
|
+
export declare function drawsJoinedRuns(text: AnyText): boolean;
|
|
5
|
+
export declare function shapeLine(text: AnyText, lineIndex: number, measured: {
|
|
6
|
+
width: number;
|
|
7
|
+
numOfSpaces: number;
|
|
8
|
+
}): {
|
|
9
|
+
width: number;
|
|
10
|
+
numOfSpaces: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function shapeWord(text: AnyText, word: readonly string[], lineIndex: number, charOffset: number, fallback: number): number;
|
|
13
|
+
export declare class ShapedIText extends IText {
|
|
14
|
+
static override type: string;
|
|
15
|
+
override _measureLine(lineIndex: number): {
|
|
16
|
+
width: number;
|
|
17
|
+
numOfSpaces: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare class ShapedTextbox extends Textbox {
|
|
21
|
+
static override type: string;
|
|
22
|
+
override _measureLine(lineIndex: number): {
|
|
23
|
+
width: number;
|
|
24
|
+
numOfSpaces: number;
|
|
25
|
+
};
|
|
26
|
+
override _measureWord(word: string[], lineIndex: number, charOffset?: number): number;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IText, Textbox } from "fabric";
|
|
2
|
+
//#region src/text/shaping.d.ts
|
|
3
|
+
export type AnyText = object;
|
|
4
|
+
export declare function drawsJoinedRuns(text: AnyText): boolean;
|
|
5
|
+
export declare function shapeLine(text: AnyText, lineIndex: number, measured: {
|
|
6
|
+
width: number;
|
|
7
|
+
numOfSpaces: number;
|
|
8
|
+
}): {
|
|
9
|
+
width: number;
|
|
10
|
+
numOfSpaces: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function shapeWord(text: AnyText, word: readonly string[], lineIndex: number, charOffset: number, fallback: number): number;
|
|
13
|
+
export declare class ShapedIText extends IText {
|
|
14
|
+
static override type: string;
|
|
15
|
+
override _measureLine(lineIndex: number): {
|
|
16
|
+
width: number;
|
|
17
|
+
numOfSpaces: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare class ShapedTextbox extends Textbox {
|
|
21
|
+
static override type: string;
|
|
22
|
+
override _measureLine(lineIndex: number): {
|
|
23
|
+
width: number;
|
|
24
|
+
numOfSpaces: number;
|
|
25
|
+
};
|
|
26
|
+
override _measureWord(word: string[], lineIndex: number, charOffset?: number): number;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { IText, Textbox, util } from "fabric";
|
|
2
|
+
//#region src/text/shaping.ts
|
|
3
|
+
const CACHE_LIMIT = 4096;
|
|
4
|
+
const widths = /* @__PURE__ */ new Map();
|
|
5
|
+
let measuringContext;
|
|
6
|
+
function context() {
|
|
7
|
+
measuringContext ?? (measuringContext = util.createCanvasElement().getContext("2d"));
|
|
8
|
+
return measuringContext;
|
|
9
|
+
}
|
|
10
|
+
function measure(ctx, font, text) {
|
|
11
|
+
if (text === "") return 0;
|
|
12
|
+
const key = `${font}\u0000${text}`;
|
|
13
|
+
const known = widths.get(key);
|
|
14
|
+
if (known !== void 0) {
|
|
15
|
+
widths.delete(key);
|
|
16
|
+
widths.set(key, known);
|
|
17
|
+
return known;
|
|
18
|
+
}
|
|
19
|
+
const width = ctx.measureText(text).width;
|
|
20
|
+
widths.set(key, width);
|
|
21
|
+
if (widths.size > CACHE_LIMIT) widths.delete(widths.keys().next().value);
|
|
22
|
+
return width;
|
|
23
|
+
}
|
|
24
|
+
function drawsJoinedRuns(text) {
|
|
25
|
+
const self = text;
|
|
26
|
+
return !self.path && self.charSpacing === 0 && !self.textAlign.includes("justify");
|
|
27
|
+
}
|
|
28
|
+
const isSpace = (grapheme) => /\s/.test(grapheme);
|
|
29
|
+
function runLefts(ctx, font, graphemes, start, end, scale) {
|
|
30
|
+
const lefts = new Array(end - start + 1);
|
|
31
|
+
let segmentStart = start;
|
|
32
|
+
let segmentLeft = 0;
|
|
33
|
+
for (let index = start; index < end; index += 1) {
|
|
34
|
+
if (index > start && isSpace(graphemes[index]) !== isSpace(graphemes[index - 1])) {
|
|
35
|
+
segmentStart = index;
|
|
36
|
+
segmentLeft = measure(ctx, font, graphemes.slice(start, index).join(""));
|
|
37
|
+
}
|
|
38
|
+
lefts[index - start] = (segmentLeft + measure(ctx, font, graphemes.slice(segmentStart, index).join(""))) * scale;
|
|
39
|
+
}
|
|
40
|
+
lefts[end - start] = measure(ctx, font, graphemes.slice(start, end).join("")) * scale;
|
|
41
|
+
return lefts;
|
|
42
|
+
}
|
|
43
|
+
function styleRuns(text, lineIndex, length) {
|
|
44
|
+
const self = text;
|
|
45
|
+
const runs = [];
|
|
46
|
+
let start = 0;
|
|
47
|
+
let style = self.getCompleteStyleDeclaration(lineIndex, 0);
|
|
48
|
+
for (let index = 1; index <= length; index += 1) {
|
|
49
|
+
const next = index < length ? self.getCompleteStyleDeclaration(lineIndex, index) : void 0;
|
|
50
|
+
if (!next || util.hasStyleChanged(style, next, false)) {
|
|
51
|
+
runs.push([
|
|
52
|
+
start,
|
|
53
|
+
index,
|
|
54
|
+
style
|
|
55
|
+
]);
|
|
56
|
+
start = index;
|
|
57
|
+
if (next) style = next;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return runs;
|
|
61
|
+
}
|
|
62
|
+
function shapeLine(text, lineIndex, measured) {
|
|
63
|
+
if (!drawsJoinedRuns(text)) return measured;
|
|
64
|
+
const self = text;
|
|
65
|
+
const graphemes = self._textLines[lineIndex] ?? [];
|
|
66
|
+
const bounds = self.__charBounds[lineIndex];
|
|
67
|
+
if (!bounds || graphemes.length === 0) return measured;
|
|
68
|
+
const ctx = context();
|
|
69
|
+
let runLeft = 0;
|
|
70
|
+
for (const [start, end, style] of styleRuns(text, lineIndex, graphemes.length)) {
|
|
71
|
+
self._setTextStyles(ctx, style, true);
|
|
72
|
+
const lefts = runLefts(ctx, ctx.font, graphemes, start, end, style.fontSize / self.CACHE_FONT_SIZE);
|
|
73
|
+
for (let index = start; index < end; index += 1) {
|
|
74
|
+
const box = bounds[index];
|
|
75
|
+
box.left = runLeft + lefts[index - start];
|
|
76
|
+
box.width = box.kernedWidth = lefts[index - start + 1] - lefts[index - start];
|
|
77
|
+
}
|
|
78
|
+
runLeft += lefts[end - start];
|
|
79
|
+
}
|
|
80
|
+
const last = bounds[graphemes.length];
|
|
81
|
+
if (last) last.left = runLeft;
|
|
82
|
+
return {
|
|
83
|
+
width: runLeft,
|
|
84
|
+
numOfSpaces: measured.numOfSpaces
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function shapeWord(text, word, lineIndex, charOffset, fallback) {
|
|
88
|
+
if (!drawsJoinedRuns(text) || word.length === 0) return fallback;
|
|
89
|
+
const self = text;
|
|
90
|
+
const ctx = context();
|
|
91
|
+
let width = 0;
|
|
92
|
+
let start = 0;
|
|
93
|
+
let style = self.getCompleteStyleDeclaration(lineIndex, charOffset);
|
|
94
|
+
for (let index = 1; index <= word.length; index += 1) {
|
|
95
|
+
const next = index < word.length ? self.getCompleteStyleDeclaration(lineIndex, charOffset + index) : void 0;
|
|
96
|
+
if (!next || util.hasStyleChanged(style, next, false)) {
|
|
97
|
+
self._setTextStyles(ctx, style, true);
|
|
98
|
+
width += measure(ctx, ctx.font, word.slice(start, index).join("")) * style.fontSize / self.CACHE_FONT_SIZE;
|
|
99
|
+
start = index;
|
|
100
|
+
if (next) style = next;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return width;
|
|
104
|
+
}
|
|
105
|
+
var ShapedIText = class extends IText {
|
|
106
|
+
_measureLine(lineIndex) {
|
|
107
|
+
return shapeLine(this, lineIndex, super._measureLine(lineIndex));
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
ShapedIText.type = "ShapedIText";
|
|
111
|
+
var ShapedTextbox = class extends Textbox {
|
|
112
|
+
_measureLine(lineIndex) {
|
|
113
|
+
return shapeLine(this, lineIndex, super._measureLine(lineIndex));
|
|
114
|
+
}
|
|
115
|
+
_measureWord(word, lineIndex, charOffset = 0) {
|
|
116
|
+
return shapeWord(this, word, lineIndex, charOffset, super._measureWord(word, lineIndex, charOffset));
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
ShapedTextbox.type = "ShapedTextbox";
|
|
120
|
+
//#endregion
|
|
121
|
+
export { ShapedIText, ShapedTextbox, drawsJoinedRuns, shapeLine, shapeWord };
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
//#region src/text/vertical-orientation.ts
|
|
2
|
+
const Orientation = {
|
|
3
|
+
Upright: 0,
|
|
4
|
+
Rotated: 1,
|
|
5
|
+
UprightShifted: 2
|
|
6
|
+
};
|
|
7
|
+
const U = Orientation.Upright;
|
|
8
|
+
const R = Orientation.Rotated;
|
|
9
|
+
const T = Orientation.UprightShifted;
|
|
10
|
+
const RANGES = [
|
|
11
|
+
[0, R],
|
|
12
|
+
[167, U],
|
|
13
|
+
[168, R],
|
|
14
|
+
[169, U],
|
|
15
|
+
[170, R],
|
|
16
|
+
[174, U],
|
|
17
|
+
[175, R],
|
|
18
|
+
[177, U],
|
|
19
|
+
[178, R],
|
|
20
|
+
[188, U],
|
|
21
|
+
[191, R],
|
|
22
|
+
[215, U],
|
|
23
|
+
[216, R],
|
|
24
|
+
[247, U],
|
|
25
|
+
[248, R],
|
|
26
|
+
[746, U],
|
|
27
|
+
[748, R],
|
|
28
|
+
[4352, U],
|
|
29
|
+
[4608, R],
|
|
30
|
+
[5121, U],
|
|
31
|
+
[5760, R],
|
|
32
|
+
[6320, U],
|
|
33
|
+
[6400, R],
|
|
34
|
+
[8214, U],
|
|
35
|
+
[8215, R],
|
|
36
|
+
[8224, U],
|
|
37
|
+
[8226, R],
|
|
38
|
+
[8240, U],
|
|
39
|
+
[8242, R],
|
|
40
|
+
[8251, U],
|
|
41
|
+
[8253, R],
|
|
42
|
+
[8258, U],
|
|
43
|
+
[8259, R],
|
|
44
|
+
[8263, U],
|
|
45
|
+
[8266, R],
|
|
46
|
+
[8273, U],
|
|
47
|
+
[8274, R],
|
|
48
|
+
[8413, U],
|
|
49
|
+
[8417, R],
|
|
50
|
+
[8448, U],
|
|
51
|
+
[8450, R],
|
|
52
|
+
[8451, U],
|
|
53
|
+
[8458, R],
|
|
54
|
+
[8463, U],
|
|
55
|
+
[8464, R],
|
|
56
|
+
[8467, U],
|
|
57
|
+
[8469, R],
|
|
58
|
+
[8470, U],
|
|
59
|
+
[8472, R],
|
|
60
|
+
[8478, U],
|
|
61
|
+
[8484, R],
|
|
62
|
+
[8485, U],
|
|
63
|
+
[8486, R],
|
|
64
|
+
[8487, U],
|
|
65
|
+
[8488, R],
|
|
66
|
+
[8489, U],
|
|
67
|
+
[8490, R],
|
|
68
|
+
[8494, U],
|
|
69
|
+
[8495, R],
|
|
70
|
+
[8501, U],
|
|
71
|
+
[8512, R],
|
|
72
|
+
[8517, U],
|
|
73
|
+
[8523, R],
|
|
74
|
+
[8524, U],
|
|
75
|
+
[8526, R],
|
|
76
|
+
[8527, U],
|
|
77
|
+
[8586, R],
|
|
78
|
+
[8588, U],
|
|
79
|
+
[8592, R],
|
|
80
|
+
[8734, U],
|
|
81
|
+
[8735, R],
|
|
82
|
+
[8756, U],
|
|
83
|
+
[8758, R],
|
|
84
|
+
[8960, U],
|
|
85
|
+
[8968, R],
|
|
86
|
+
[8972, U],
|
|
87
|
+
[8992, R],
|
|
88
|
+
[8996, U],
|
|
89
|
+
[9001, R],
|
|
90
|
+
[9003, U],
|
|
91
|
+
[9004, R],
|
|
92
|
+
[9085, U],
|
|
93
|
+
[9115, R],
|
|
94
|
+
[9150, U],
|
|
95
|
+
[9166, R],
|
|
96
|
+
[9167, U],
|
|
97
|
+
[9168, R],
|
|
98
|
+
[9169, U],
|
|
99
|
+
[9180, R],
|
|
100
|
+
[9186, U],
|
|
101
|
+
[9251, R],
|
|
102
|
+
[9252, U],
|
|
103
|
+
[9472, R],
|
|
104
|
+
[9632, U],
|
|
105
|
+
[9754, R],
|
|
106
|
+
[9760, U],
|
|
107
|
+
[10088, R],
|
|
108
|
+
[10102, U],
|
|
109
|
+
[10132, R],
|
|
110
|
+
[11026, U],
|
|
111
|
+
[11056, R],
|
|
112
|
+
[11088, U],
|
|
113
|
+
[11098, R],
|
|
114
|
+
[11192, U],
|
|
115
|
+
[11264, R],
|
|
116
|
+
[11904, U],
|
|
117
|
+
[12289, T],
|
|
118
|
+
[12291, U],
|
|
119
|
+
[12296, R],
|
|
120
|
+
[12306, U],
|
|
121
|
+
[12308, R],
|
|
122
|
+
[12320, U],
|
|
123
|
+
[12336, R],
|
|
124
|
+
[12337, U],
|
|
125
|
+
[12448, R],
|
|
126
|
+
[12449, U],
|
|
127
|
+
[12540, R],
|
|
128
|
+
[12541, U],
|
|
129
|
+
[42192, R],
|
|
130
|
+
[43360, U],
|
|
131
|
+
[43392, R],
|
|
132
|
+
[44032, U],
|
|
133
|
+
[55296, R],
|
|
134
|
+
[57344, U],
|
|
135
|
+
[64256, R],
|
|
136
|
+
[65040, U],
|
|
137
|
+
[65056, R],
|
|
138
|
+
[65072, U],
|
|
139
|
+
[65104, T],
|
|
140
|
+
[65107, U],
|
|
141
|
+
[65112, R],
|
|
142
|
+
[65119, U],
|
|
143
|
+
[65123, R],
|
|
144
|
+
[65124, U],
|
|
145
|
+
[65127, R],
|
|
146
|
+
[65128, U],
|
|
147
|
+
[65136, R],
|
|
148
|
+
[65281, U],
|
|
149
|
+
[65288, R],
|
|
150
|
+
[65290, U],
|
|
151
|
+
[65292, T],
|
|
152
|
+
[65293, R],
|
|
153
|
+
[65294, T],
|
|
154
|
+
[65295, U],
|
|
155
|
+
[65306, R],
|
|
156
|
+
[65311, U],
|
|
157
|
+
[65339, R],
|
|
158
|
+
[65340, U],
|
|
159
|
+
[65341, R],
|
|
160
|
+
[65342, U],
|
|
161
|
+
[65343, R],
|
|
162
|
+
[65344, U],
|
|
163
|
+
[65371, R],
|
|
164
|
+
[65377, R],
|
|
165
|
+
[65504, U],
|
|
166
|
+
[65507, R],
|
|
167
|
+
[65508, U],
|
|
168
|
+
[65512, R],
|
|
169
|
+
[126976, U],
|
|
170
|
+
[129792, R],
|
|
171
|
+
[131072, U],
|
|
172
|
+
[262142, R]
|
|
173
|
+
];
|
|
174
|
+
const starts = Uint32Array.from(RANGES, ([start]) => start);
|
|
175
|
+
const classes = Uint8Array.from(RANGES, ([, orientation]) => orientation);
|
|
176
|
+
function orientationOfCodePoint(codePoint) {
|
|
177
|
+
let low = 0;
|
|
178
|
+
let high = starts.length - 1;
|
|
179
|
+
while (low < high) {
|
|
180
|
+
const middle = low + high + 1 >> 1;
|
|
181
|
+
if (starts[middle] <= codePoint) low = middle;
|
|
182
|
+
else high = middle - 1;
|
|
183
|
+
}
|
|
184
|
+
return classes[low];
|
|
185
|
+
}
|
|
186
|
+
function orientationOf(grapheme) {
|
|
187
|
+
return grapheme === "" ? Orientation.Rotated : orientationOfCodePoint(grapheme.codePointAt(0));
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
190
|
+
exports.Orientation = Orientation;
|
|
191
|
+
exports.orientationOf = orientationOf;
|
|
192
|
+
exports.orientationOfCodePoint = orientationOfCodePoint;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/text/vertical-orientation.d.ts
|
|
2
|
+
export declare const Orientation: {
|
|
3
|
+
readonly Upright: 0;
|
|
4
|
+
readonly Rotated: 1;
|
|
5
|
+
readonly UprightShifted: 2;
|
|
6
|
+
};
|
|
7
|
+
export type Orientation = (typeof Orientation)[keyof typeof Orientation];
|
|
8
|
+
export declare function orientationOfCodePoint(codePoint: number): Orientation;
|
|
9
|
+
export declare function orientationOf(grapheme: string): Orientation;
|
|
10
|
+
//#endregion
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/text/vertical-orientation.d.ts
|
|
2
|
+
export declare const Orientation: {
|
|
3
|
+
readonly Upright: 0;
|
|
4
|
+
readonly Rotated: 1;
|
|
5
|
+
readonly UprightShifted: 2;
|
|
6
|
+
};
|
|
7
|
+
export type Orientation = (typeof Orientation)[keyof typeof Orientation];
|
|
8
|
+
export declare function orientationOfCodePoint(codePoint: number): Orientation;
|
|
9
|
+
export declare function orientationOf(grapheme: string): Orientation;
|
|
10
|
+
//#endregion
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
//#region src/text/vertical-orientation.ts
|
|
2
|
+
const Orientation = {
|
|
3
|
+
Upright: 0,
|
|
4
|
+
Rotated: 1,
|
|
5
|
+
UprightShifted: 2
|
|
6
|
+
};
|
|
7
|
+
const U = Orientation.Upright;
|
|
8
|
+
const R = Orientation.Rotated;
|
|
9
|
+
const T = Orientation.UprightShifted;
|
|
10
|
+
const RANGES = [
|
|
11
|
+
[0, R],
|
|
12
|
+
[167, U],
|
|
13
|
+
[168, R],
|
|
14
|
+
[169, U],
|
|
15
|
+
[170, R],
|
|
16
|
+
[174, U],
|
|
17
|
+
[175, R],
|
|
18
|
+
[177, U],
|
|
19
|
+
[178, R],
|
|
20
|
+
[188, U],
|
|
21
|
+
[191, R],
|
|
22
|
+
[215, U],
|
|
23
|
+
[216, R],
|
|
24
|
+
[247, U],
|
|
25
|
+
[248, R],
|
|
26
|
+
[746, U],
|
|
27
|
+
[748, R],
|
|
28
|
+
[4352, U],
|
|
29
|
+
[4608, R],
|
|
30
|
+
[5121, U],
|
|
31
|
+
[5760, R],
|
|
32
|
+
[6320, U],
|
|
33
|
+
[6400, R],
|
|
34
|
+
[8214, U],
|
|
35
|
+
[8215, R],
|
|
36
|
+
[8224, U],
|
|
37
|
+
[8226, R],
|
|
38
|
+
[8240, U],
|
|
39
|
+
[8242, R],
|
|
40
|
+
[8251, U],
|
|
41
|
+
[8253, R],
|
|
42
|
+
[8258, U],
|
|
43
|
+
[8259, R],
|
|
44
|
+
[8263, U],
|
|
45
|
+
[8266, R],
|
|
46
|
+
[8273, U],
|
|
47
|
+
[8274, R],
|
|
48
|
+
[8413, U],
|
|
49
|
+
[8417, R],
|
|
50
|
+
[8448, U],
|
|
51
|
+
[8450, R],
|
|
52
|
+
[8451, U],
|
|
53
|
+
[8458, R],
|
|
54
|
+
[8463, U],
|
|
55
|
+
[8464, R],
|
|
56
|
+
[8467, U],
|
|
57
|
+
[8469, R],
|
|
58
|
+
[8470, U],
|
|
59
|
+
[8472, R],
|
|
60
|
+
[8478, U],
|
|
61
|
+
[8484, R],
|
|
62
|
+
[8485, U],
|
|
63
|
+
[8486, R],
|
|
64
|
+
[8487, U],
|
|
65
|
+
[8488, R],
|
|
66
|
+
[8489, U],
|
|
67
|
+
[8490, R],
|
|
68
|
+
[8494, U],
|
|
69
|
+
[8495, R],
|
|
70
|
+
[8501, U],
|
|
71
|
+
[8512, R],
|
|
72
|
+
[8517, U],
|
|
73
|
+
[8523, R],
|
|
74
|
+
[8524, U],
|
|
75
|
+
[8526, R],
|
|
76
|
+
[8527, U],
|
|
77
|
+
[8586, R],
|
|
78
|
+
[8588, U],
|
|
79
|
+
[8592, R],
|
|
80
|
+
[8734, U],
|
|
81
|
+
[8735, R],
|
|
82
|
+
[8756, U],
|
|
83
|
+
[8758, R],
|
|
84
|
+
[8960, U],
|
|
85
|
+
[8968, R],
|
|
86
|
+
[8972, U],
|
|
87
|
+
[8992, R],
|
|
88
|
+
[8996, U],
|
|
89
|
+
[9001, R],
|
|
90
|
+
[9003, U],
|
|
91
|
+
[9004, R],
|
|
92
|
+
[9085, U],
|
|
93
|
+
[9115, R],
|
|
94
|
+
[9150, U],
|
|
95
|
+
[9166, R],
|
|
96
|
+
[9167, U],
|
|
97
|
+
[9168, R],
|
|
98
|
+
[9169, U],
|
|
99
|
+
[9180, R],
|
|
100
|
+
[9186, U],
|
|
101
|
+
[9251, R],
|
|
102
|
+
[9252, U],
|
|
103
|
+
[9472, R],
|
|
104
|
+
[9632, U],
|
|
105
|
+
[9754, R],
|
|
106
|
+
[9760, U],
|
|
107
|
+
[10088, R],
|
|
108
|
+
[10102, U],
|
|
109
|
+
[10132, R],
|
|
110
|
+
[11026, U],
|
|
111
|
+
[11056, R],
|
|
112
|
+
[11088, U],
|
|
113
|
+
[11098, R],
|
|
114
|
+
[11192, U],
|
|
115
|
+
[11264, R],
|
|
116
|
+
[11904, U],
|
|
117
|
+
[12289, T],
|
|
118
|
+
[12291, U],
|
|
119
|
+
[12296, R],
|
|
120
|
+
[12306, U],
|
|
121
|
+
[12308, R],
|
|
122
|
+
[12320, U],
|
|
123
|
+
[12336, R],
|
|
124
|
+
[12337, U],
|
|
125
|
+
[12448, R],
|
|
126
|
+
[12449, U],
|
|
127
|
+
[12540, R],
|
|
128
|
+
[12541, U],
|
|
129
|
+
[42192, R],
|
|
130
|
+
[43360, U],
|
|
131
|
+
[43392, R],
|
|
132
|
+
[44032, U],
|
|
133
|
+
[55296, R],
|
|
134
|
+
[57344, U],
|
|
135
|
+
[64256, R],
|
|
136
|
+
[65040, U],
|
|
137
|
+
[65056, R],
|
|
138
|
+
[65072, U],
|
|
139
|
+
[65104, T],
|
|
140
|
+
[65107, U],
|
|
141
|
+
[65112, R],
|
|
142
|
+
[65119, U],
|
|
143
|
+
[65123, R],
|
|
144
|
+
[65124, U],
|
|
145
|
+
[65127, R],
|
|
146
|
+
[65128, U],
|
|
147
|
+
[65136, R],
|
|
148
|
+
[65281, U],
|
|
149
|
+
[65288, R],
|
|
150
|
+
[65290, U],
|
|
151
|
+
[65292, T],
|
|
152
|
+
[65293, R],
|
|
153
|
+
[65294, T],
|
|
154
|
+
[65295, U],
|
|
155
|
+
[65306, R],
|
|
156
|
+
[65311, U],
|
|
157
|
+
[65339, R],
|
|
158
|
+
[65340, U],
|
|
159
|
+
[65341, R],
|
|
160
|
+
[65342, U],
|
|
161
|
+
[65343, R],
|
|
162
|
+
[65344, U],
|
|
163
|
+
[65371, R],
|
|
164
|
+
[65377, R],
|
|
165
|
+
[65504, U],
|
|
166
|
+
[65507, R],
|
|
167
|
+
[65508, U],
|
|
168
|
+
[65512, R],
|
|
169
|
+
[126976, U],
|
|
170
|
+
[129792, R],
|
|
171
|
+
[131072, U],
|
|
172
|
+
[262142, R]
|
|
173
|
+
];
|
|
174
|
+
const starts = Uint32Array.from(RANGES, ([start]) => start);
|
|
175
|
+
const classes = Uint8Array.from(RANGES, ([, orientation]) => orientation);
|
|
176
|
+
function orientationOfCodePoint(codePoint) {
|
|
177
|
+
let low = 0;
|
|
178
|
+
let high = starts.length - 1;
|
|
179
|
+
while (low < high) {
|
|
180
|
+
const middle = low + high + 1 >> 1;
|
|
181
|
+
if (starts[middle] <= codePoint) low = middle;
|
|
182
|
+
else high = middle - 1;
|
|
183
|
+
}
|
|
184
|
+
return classes[low];
|
|
185
|
+
}
|
|
186
|
+
function orientationOf(grapheme) {
|
|
187
|
+
return grapheme === "" ? Orientation.Rotated : orientationOfCodePoint(grapheme.codePointAt(0));
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
190
|
+
export { Orientation, orientationOf, orientationOfCodePoint };
|