@pixerate/editor 0.192.0 → 0.193.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/animation-editor/index.cjs +56 -56
- package/dist/animation-editor/index.js +2 -2
- package/dist/{chunk-ZQGZWFPU.cjs → chunk-3T5VCDIV.cjs} +97 -5
- package/dist/{chunk-RQ2EM5TY.js → chunk-5OC22IEO.js} +97 -5
- package/dist/{chunk-EGZM52EO.cjs → chunk-BRKVNXDZ.cjs} +354 -125
- package/dist/{chunk-XCDGM7TD.cjs → chunk-FR2Q2LVF.cjs} +35 -35
- package/dist/{chunk-LPIKXPBM.js → chunk-GHCXLQ47.js} +262 -33
- package/dist/{chunk-VRXXAXUT.js → chunk-MLC7HUHO.js} +1 -1
- package/dist/{chunk-2UR4OX3B.cjs → chunk-UYXL6ZWQ.cjs} +114 -97
- package/dist/{chunk-TXYXF32N.js → chunk-ZIDUPSP4.js} +35 -18
- package/dist/image-editor/controller.d.cts +16 -6
- package/dist/image-editor/controller.d.ts +16 -6
- package/dist/image-editor/index.cjs +867 -831
- package/dist/image-editor/index.js +103 -67
- package/dist/image-editor/layers/model.d.cts +7 -2
- package/dist/image-editor/layers/model.d.ts +7 -2
- package/dist/image-editor/layers/serialize.d.cts +2 -0
- package/dist/image-editor/layers/serialize.d.ts +2 -0
- package/dist/image-editor/layers/shape-type-ui.d.cts +8 -2
- package/dist/image-editor/layers/shape-type-ui.d.ts +8 -2
- package/dist/image-editor/layers/text.d.cts +6 -2
- package/dist/image-editor/layers/text.d.ts +6 -2
- package/dist/image-editor/psd/type.d.cts +2 -1
- package/dist/image-editor/psd/type.d.ts +2 -1
- package/dist/image-editor/tools.d.cts +1 -1
- package/dist/image-editor/tools.d.ts +1 -1
- package/dist/image-editor/type-tools.d.cts +2 -2
- package/dist/image-editor/type-tools.d.ts +2 -2
- package/dist/paint-editor/index.cjs +7 -7
- package/dist/paint-editor/index.js +2 -2
- package/dist/text/layout.d.cts +93 -12
- package/dist/text/layout.d.ts +93 -12
- package/dist/text/opentype.d.cts +13 -3
- package/dist/text/opentype.d.ts +13 -3
- package/dist/text/shapers.d.cts +12 -0
- package/dist/text/shapers.d.ts +12 -0
- package/dist/text/types.d.cts +36 -2
- package/dist/text/types.d.ts +36 -2
- package/dist/vector/controller.d.cts +8 -0
- package/dist/vector/controller.d.ts +8 -0
- package/dist/vector/index.cjs +1039 -967
- package/dist/vector/index.js +90 -18
- package/dist/vector/text.d.cts +5 -3
- package/dist/vector/text.d.ts +5 -3
- package/dist/vector/textPanel.d.cts +6 -0
- package/dist/vector/textPanel.d.ts +6 -0
- package/dist/vector/types.d.cts +9 -0
- package/dist/vector/types.d.ts +9 -0
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +4 -3
- package/skills/pixerate-image-editor/references/shapes-and-type.md +17 -5
- package/skills/pixerate-vector/SKILL.md +9 -3
package/dist/vector/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
traceField,
|
|
17
17
|
traceVectorImage,
|
|
18
18
|
vectorTraceContours
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-5OC22IEO.js";
|
|
20
20
|
import {
|
|
21
21
|
applyHomography,
|
|
22
22
|
homographyFromPoints,
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
reverseMorphContour,
|
|
44
44
|
subpathToMorphContour,
|
|
45
45
|
turnMorphContour
|
|
46
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-MLC7HUHO.js";
|
|
47
47
|
import {
|
|
48
48
|
DEFAULT_VECTOR_FONT,
|
|
49
49
|
IDENTITY_MATRIX,
|
|
@@ -218,6 +218,7 @@ import {
|
|
|
218
218
|
knifePath,
|
|
219
219
|
layoutVectorText,
|
|
220
220
|
lineSubpath,
|
|
221
|
+
lineToTextSpace,
|
|
221
222
|
locateVectorNode,
|
|
222
223
|
mapBezierPath,
|
|
223
224
|
mapVectorGradient,
|
|
@@ -337,6 +338,8 @@ import {
|
|
|
337
338
|
subpathsToBezier,
|
|
338
339
|
sweepPath,
|
|
339
340
|
taperWaveFactor,
|
|
341
|
+
textArrowStep,
|
|
342
|
+
textLineMove,
|
|
340
343
|
tintVectorNode,
|
|
341
344
|
transformVectorEffects,
|
|
342
345
|
transformVectorGradient,
|
|
@@ -482,6 +485,7 @@ import {
|
|
|
482
485
|
vectorTextHasOutlines,
|
|
483
486
|
vectorTextIndexAt,
|
|
484
487
|
vectorTextName,
|
|
488
|
+
vectorTextOrientation,
|
|
485
489
|
vectorTextPaintSource,
|
|
486
490
|
vectorTextPaths,
|
|
487
491
|
vectorTextRange,
|
|
@@ -512,7 +516,7 @@ import {
|
|
|
512
516
|
withVectorStrokes,
|
|
513
517
|
withVectorTargetPaint,
|
|
514
518
|
zigzagPaths
|
|
515
|
-
} from "../chunk-
|
|
519
|
+
} from "../chunk-GHCXLQ47.js";
|
|
516
520
|
import "../chunk-YXKLVD56.js";
|
|
517
521
|
import {
|
|
518
522
|
createProvenance
|
|
@@ -13503,6 +13507,8 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
13503
13507
|
const own = {};
|
|
13504
13508
|
for (const key of VECTOR_STYLE_KEYS) if (input[key] !== void 0) own[key] = input[key];
|
|
13505
13509
|
const text = input.text.replace(/\r\n?/g, "\n");
|
|
13510
|
+
const orientation = vectorTextOrientation(input.orientation);
|
|
13511
|
+
if (orientation && frame.kind === "path") throw new VectorTextError("Text on a path cannot be vertical; leave orientation out, or set point or area text.");
|
|
13506
13512
|
const node = {
|
|
13507
13513
|
id: this.newId(),
|
|
13508
13514
|
type: "text",
|
|
@@ -13511,7 +13517,8 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
13511
13517
|
text,
|
|
13512
13518
|
font,
|
|
13513
13519
|
...Object.keys(paragraph).length ? { paragraph } : {},
|
|
13514
|
-
frame
|
|
13520
|
+
frame,
|
|
13521
|
+
...orientation ? { orientation } : {}
|
|
13515
13522
|
};
|
|
13516
13523
|
return withStyle(node, own);
|
|
13517
13524
|
}
|
|
@@ -13602,12 +13609,19 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
13602
13609
|
n2 = { ...n2, paragraph };
|
|
13603
13610
|
if (!Object.keys(paragraph).length) delete n2.paragraph;
|
|
13604
13611
|
}
|
|
13612
|
+
if (patch.orientation !== void 0) {
|
|
13613
|
+
const orientation = vectorTextOrientation(patch.orientation);
|
|
13614
|
+
if (orientation && n2.frame.kind === "path") throw new VectorTextError("Text on a path cannot be vertical; set it as point or area text first.");
|
|
13615
|
+
n2 = { ...n2 };
|
|
13616
|
+
if (orientation) n2.orientation = orientation;
|
|
13617
|
+
else delete n2.orientation;
|
|
13618
|
+
}
|
|
13605
13619
|
next.set(t.id, n2);
|
|
13606
13620
|
}
|
|
13607
13621
|
} catch (e) {
|
|
13608
13622
|
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
13609
13623
|
}
|
|
13610
|
-
this.change(patch.paragraph && !patch.style ? "Paragraph Style" : "Character Style", () => this.setDoc(mapTree(this.doc.nodes, (n2) => next.get(n2.id) ?? n2)), options.merge);
|
|
13624
|
+
this.change(patch.orientation !== void 0 && !patch.style && !patch.paragraph ? "Type Orientation" : patch.paragraph && !patch.style ? "Paragraph Style" : "Character Style", () => this.setDoc(mapTree(this.doc.nodes, (n2) => next.get(n2.id) ?? n2)), options.merge);
|
|
13611
13625
|
return { ok: true };
|
|
13612
13626
|
}
|
|
13613
13627
|
/** Changes paragraph fields (`align`, `autoLeading`, indents, spacing; `null` clears) of text node `id`. One undo step. */
|
|
@@ -13637,7 +13651,12 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
13637
13651
|
const cur = n2.frame;
|
|
13638
13652
|
const box = layout.bounds ?? { x: 0, y: 0, width: 0, height: 0 };
|
|
13639
13653
|
let frame;
|
|
13640
|
-
if (kind === "
|
|
13654
|
+
if (n2.orientation === "vertical" && kind === "path") throw new VectorTextError("Text on a path cannot be vertical; call vector.setTextOrientation with horizontal first.");
|
|
13655
|
+
if (kind === "point" && n2.orientation === "vertical" && cur.kind !== "point") {
|
|
13656
|
+
const l = layout.text.lines[0];
|
|
13657
|
+
const at = l ? lineToTextSpace(layout.text, { x: 0, y: l.baseline }) : { x: 0, y: 0 };
|
|
13658
|
+
frame = sanitizeVectorTextFrame({ kind: "point", x: patch.x ?? layout.origin.x + at.x, y: patch.y ?? layout.origin.y + at.y });
|
|
13659
|
+
} else if (kind === "point") {
|
|
13641
13660
|
const first = layout.lines[0];
|
|
13642
13661
|
const x = patch.x ?? (cur.kind === "point" ? cur.x : first?.x ?? box.x);
|
|
13643
13662
|
const y = patch.y ?? (cur.kind === "point" ? cur.y : first?.baseline ?? box.y);
|
|
@@ -13657,6 +13676,21 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
13657
13676
|
return { ...n2, frame };
|
|
13658
13677
|
});
|
|
13659
13678
|
}
|
|
13679
|
+
/**
|
|
13680
|
+
* Horizontal ↔ vertical text (Type › Type Orientation) for point and area text: the text, styles
|
|
13681
|
+
* and frame stay; lines become columns running down, right to left, or back. One undo step.
|
|
13682
|
+
*/
|
|
13683
|
+
setTextOrientation(id, orientation) {
|
|
13684
|
+
return this.editTextNode(id, "Type Orientation", (n2) => {
|
|
13685
|
+
const next = vectorTextOrientation(orientation);
|
|
13686
|
+
if (next && n2.frame.kind === "path") throw new VectorTextError("Text on a path cannot be vertical; set it as point or area text first (vector.setTextFrame).");
|
|
13687
|
+
if (next === n2.orientation) return n2;
|
|
13688
|
+
const out = { ...n2 };
|
|
13689
|
+
if (next) out.orientation = next;
|
|
13690
|
+
else delete out.orientation;
|
|
13691
|
+
return out;
|
|
13692
|
+
});
|
|
13693
|
+
}
|
|
13660
13694
|
/**
|
|
13661
13695
|
* Turns path `pathId` into text set along it (Type on a Path): a text node in its place, its
|
|
13662
13696
|
* anchors the text's path, its paint dropped for the text defaults (or `input`'s). Returns the
|
|
@@ -13829,7 +13863,11 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
13829
13863
|
return false;
|
|
13830
13864
|
}
|
|
13831
13865
|
const text = node.text;
|
|
13832
|
-
|
|
13866
|
+
let key = input.key;
|
|
13867
|
+
if (node.orientation === "vertical" && node.frame.kind !== "path" && (key === "ArrowLeft" || key === "ArrowRight" || key === "ArrowUp" || key === "ArrowDown")) {
|
|
13868
|
+
const step = textArrowStep("vertical", key);
|
|
13869
|
+
key = step === "previous" ? "ArrowLeft" : step === "next" ? "ArrowRight" : step === "line-before" ? "ArrowUp" : "ArrowDown";
|
|
13870
|
+
}
|
|
13833
13871
|
const move = (to) => {
|
|
13834
13872
|
const focus = Math.max(0, Math.min(text.length, to));
|
|
13835
13873
|
this.textEdit = { ...t, focus, anchor: input.shift ? t.anchor : focus };
|
|
@@ -13918,11 +13956,7 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
13918
13956
|
lineMove(node, index, dir) {
|
|
13919
13957
|
const layout = layoutVectorText(node);
|
|
13920
13958
|
if (node.frame.kind === "path") return dir < 0 ? 0 : node.text.length;
|
|
13921
|
-
|
|
13922
|
-
const lines = layout.text.lines;
|
|
13923
|
-
const target = lines[c.line + dir];
|
|
13924
|
-
if (!target) return dir < 0 ? 0 : node.text.length;
|
|
13925
|
-
return vectorTextIndexAt(node, { x: c.top.x, y: layout.origin.y + target.baseline });
|
|
13959
|
+
return textLineMove(layout.text, index, dir, node.text.length);
|
|
13926
13960
|
}
|
|
13927
13961
|
/** The topmost node of `type` under `p` (inside groups too, hit where it draws), or null. */
|
|
13928
13962
|
hitOfType(p, type) {
|
|
@@ -15427,6 +15461,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15427
15461
|
runs,
|
|
15428
15462
|
paragraph: t.paragraph ?? {},
|
|
15429
15463
|
frame: t.frame,
|
|
15464
|
+
orientation: t.orientation ?? "horizontal",
|
|
15430
15465
|
fill: t.fill ?? null,
|
|
15431
15466
|
stroke: t.stroke ?? null,
|
|
15432
15467
|
lines: layout.lines.map((l) => ({ start: l.start, end: l.end, text: t.text.slice(l.start, l.end) })),
|
|
@@ -15446,7 +15481,13 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15446
15481
|
leading: { type: ["number", "null"], minimum: 0, maximum: 1e4, description: "Baseline-to-baseline distance in document units; null for auto (autoLeading \xD7 size)." },
|
|
15447
15482
|
baselineShift: { type: ["number", "null"], minimum: -5e3, maximum: 5e3, description: "Raises (positive) or lowers the text, document units (0 default)." },
|
|
15448
15483
|
underline: { type: "boolean", description: "Underline." },
|
|
15449
|
-
strikethrough: { type: "boolean", description: "Strike through." }
|
|
15484
|
+
strikethrough: { type: "boolean", description: "Strike through." },
|
|
15485
|
+
upright: { type: "boolean", description: "Vertical text only: Latin and other horizontal-script characters stand upright, one under the other, instead of turned sideways (default false)." }
|
|
15486
|
+
};
|
|
15487
|
+
const ORIENTATION = {
|
|
15488
|
+
type: "string",
|
|
15489
|
+
enum: ["horizontal", "vertical"],
|
|
15490
|
+
description: "horizontal (default): lines left to right, stacked down. vertical: columns top to bottom, stacked right to left; CJK stands upright, Latin turns sideways unless styled upright. Point and area text only."
|
|
15450
15491
|
};
|
|
15451
15492
|
const PARAGRAPH_PROPS = {
|
|
15452
15493
|
align: { type: "string", enum: ["left", "center", "right", "justify"], description: "Alignment (default left). justify stretches area text lines but the last of a paragraph, and spreads path text over the path." },
|
|
@@ -15489,7 +15530,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15489
15530
|
id: `${prefix}addText`,
|
|
15490
15531
|
label: "Add Text\u2026",
|
|
15491
15532
|
keywords: ["text", "type", "label", "title", "headline", "caption", "paragraph", "words"],
|
|
15492
|
-
description:
|
|
15533
|
+
description: "Adds text: point text whose first baseline starts at (x, y), area text wrapped in a box (x, y, width, height), or text along `path` (SVG path data, document units). textOrientation vertical sets point or area text in columns running down, right to left: (x, y) is then the top of the first column's centre line, and area text fills its box from the right edge. Paragraphs are separated by \"\\n\". Paint defaults to black with no stroke; style it with fill / stroke here or vector.setStyle. One undo step. Returns vector.getText's summary of the new text (id, lines, bounds, overflow).",
|
|
15493
15534
|
params: {
|
|
15494
15535
|
type: "object",
|
|
15495
15536
|
properties: {
|
|
@@ -15502,6 +15543,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15502
15543
|
...PATH_TEXT_PROPS,
|
|
15503
15544
|
font: { type: "object", properties: FONT_PROPS, additionalProperties: false, description: "Character style (default the editor's text defaults: 24 sans-serif)." },
|
|
15504
15545
|
paragraph: { type: "object", properties: PARAGRAPH_PROPS, additionalProperties: false, description: "Paragraph style." },
|
|
15546
|
+
textOrientation: { ...ORIENTATION, description: `${ORIENTATION.description} Named textOrientation because orientation is the path text option.` },
|
|
15505
15547
|
name: { type: "string", description: "Layer name (default the text's start)." },
|
|
15506
15548
|
fill: PAINT,
|
|
15507
15549
|
stroke: PAINT,
|
|
@@ -15524,6 +15566,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15524
15566
|
...params.path !== void 0 ? { path: params.path, pathOptions } : {},
|
|
15525
15567
|
...params.font ? { font: params.font } : {},
|
|
15526
15568
|
...params.paragraph ? { paragraph: params.paragraph } : {},
|
|
15569
|
+
...params.textOrientation !== void 0 ? { orientation: params.textOrientation } : {},
|
|
15527
15570
|
...params.fill !== void 0 ? { fill: checkPaint(params.fill, "fill") } : {},
|
|
15528
15571
|
...params.stroke !== void 0 ? { stroke: checkPaint(params.stroke, "stroke") } : {}
|
|
15529
15572
|
}, parentOf(params.parentId));
|
|
@@ -15539,7 +15582,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15539
15582
|
label: "Get Text",
|
|
15540
15583
|
readOnly: true,
|
|
15541
15584
|
keywords: ["text", "type", "read", "font", "runs"],
|
|
15542
|
-
description: "Reads a text node: its text, base font, runs (styled ranges as { start, end, style } in UTF-16 code units; style fields override the font, fill a range's colour), paragraph style, frame (point / area / path), fill and stroke, the laid-out lines (start, end, text), document bounds, overflow (text that does not fit its box or path), whether it draws as outlines, the shaper and missing fonts. Use the ranges with vector.setText and vector.setTextStyle.",
|
|
15585
|
+
description: "Reads a text node: its text, base font, runs (styled ranges as { start, end, style } in UTF-16 code units; style fields override the font, fill a range's colour), paragraph style, frame (point / area / path), orientation (horizontal / vertical), fill and stroke, the laid-out lines (start, end, text), document bounds, overflow (text that does not fit its box or path), whether it draws as outlines, the shaper and missing fonts. Use the ranges with vector.setText and vector.setTextStyle.",
|
|
15543
15586
|
params: { type: "object", properties: { id: { type: "string", description: "Text node id (from vector.list)." } }, required: ["id"], additionalProperties: false },
|
|
15544
15587
|
run: (_ctx, params) => textSummary(params.id)
|
|
15545
15588
|
},
|
|
@@ -15626,6 +15669,24 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15626
15669
|
return textSummary(id);
|
|
15627
15670
|
}
|
|
15628
15671
|
},
|
|
15672
|
+
{
|
|
15673
|
+
...base,
|
|
15674
|
+
id: `${prefix}setTextOrientation`,
|
|
15675
|
+
label: "Type Orientation",
|
|
15676
|
+
keywords: ["vertical text", "vertical type", "horizontal text", "tategaki", "columns", "cjk", "japanese", "chinese", "orientation"],
|
|
15677
|
+
description: "Sets point or area text horizontal (lines left to right) or vertical (columns top to bottom, stacked right to left; CJK upright, Latin turned sideways unless styled upright). The text, styles and frame stay. Text on a path cannot be vertical. One undo step. Returns the text summary with its orientation and lines (columns).",
|
|
15678
|
+
params: {
|
|
15679
|
+
type: "object",
|
|
15680
|
+
properties: { id: { type: "string", description: "Text node id." }, orientation: { ...ORIENTATION, description: "horizontal or vertical." } },
|
|
15681
|
+
required: ["id", "orientation"],
|
|
15682
|
+
additionalProperties: false
|
|
15683
|
+
},
|
|
15684
|
+
undoable: true,
|
|
15685
|
+
run: (_ctx, params) => {
|
|
15686
|
+
check2(controller.setTextOrientation(params.id, params.orientation));
|
|
15687
|
+
return textSummary(params.id);
|
|
15688
|
+
}
|
|
15689
|
+
},
|
|
15629
15690
|
{
|
|
15630
15691
|
...base,
|
|
15631
15692
|
id: `${prefix}typeOnPath`,
|
|
@@ -18274,7 +18335,7 @@ var VECTOR_FONT_WEIGHTS = [
|
|
|
18274
18335
|
{ value: 700, label: "Bold" },
|
|
18275
18336
|
{ value: 900, label: "Black" }
|
|
18276
18337
|
];
|
|
18277
|
-
var FIELDS = ["fontFamily", "fontWeight", "italic", "fontSize", "tracking", "leading", "baselineShift", "underline", "strikethrough"];
|
|
18338
|
+
var FIELDS = ["fontFamily", "fontWeight", "italic", "fontSize", "tracking", "leading", "baselineShift", "underline", "strikethrough", "upright"];
|
|
18278
18339
|
function getVectorTextPanel(state) {
|
|
18279
18340
|
const nodes = [];
|
|
18280
18341
|
for (const id of state.selection) {
|
|
@@ -18305,7 +18366,7 @@ function getVectorTextPanel(state) {
|
|
|
18305
18366
|
styles.push(font2);
|
|
18306
18367
|
}
|
|
18307
18368
|
const same = (k) => {
|
|
18308
|
-
const values = styles.map((s) => s[k] ?? (k === "italic" || k === "underline" || k === "strikethrough" ? false : k === "leading" ? null : k === "tracking" || k === "baselineShift" ? 0 : null));
|
|
18369
|
+
const values = styles.map((s) => s[k] ?? (k === "italic" || k === "underline" || k === "strikethrough" || k === "upright" ? false : k === "leading" ? null : k === "tracking" || k === "baselineShift" ? 0 : null));
|
|
18309
18370
|
return values.every((v) => v === values[0]) ? values[0] ?? null : null;
|
|
18310
18371
|
};
|
|
18311
18372
|
const font = Object.fromEntries(FIELDS.map((k) => [k, same(k)]));
|
|
@@ -18313,7 +18374,11 @@ function getVectorTextPanel(state) {
|
|
|
18313
18374
|
const align = alignSource.every((a) => a === alignSource[0]) ? alignSource[0] : null;
|
|
18314
18375
|
const ids = target === "range" ? [edited.id] : nodes.map((n2) => n2.id);
|
|
18315
18376
|
const frameNode = target === "range" ? edited : nodes.length === 1 ? nodes[0] : void 0;
|
|
18316
|
-
|
|
18377
|
+
const edits = target === "range" ? [edited] : nodes;
|
|
18378
|
+
const orientations = edits.map((n2) => n2.orientation ?? "horizontal");
|
|
18379
|
+
const orientation = orientations.length && orientations.every((o) => o === orientations[0]) ? orientations[0] : null;
|
|
18380
|
+
const canOrient = edits.length > 0 && edits.every((n2) => n2.frame.kind !== "path");
|
|
18381
|
+
return { target, ids, font, align, frame: frameNode?.frame.kind ?? null, orientation, canOrient, families: vectorTextFamilies(), outlines: vectorTextHasOutlines(), pathId };
|
|
18317
18382
|
}
|
|
18318
18383
|
function applyVectorTextStyle(controller, patch, options = {}) {
|
|
18319
18384
|
const state = controller.getState();
|
|
@@ -18339,6 +18404,11 @@ function applyVectorParagraphStyle(controller, patch, options = {}) {
|
|
|
18339
18404
|
}
|
|
18340
18405
|
controller.styleTexts({ paragraph: patch }, { ids: panel.ids, ...options });
|
|
18341
18406
|
}
|
|
18407
|
+
function applyVectorTextOrientation(controller, orientation) {
|
|
18408
|
+
const panel = getVectorTextPanel(controller.getState());
|
|
18409
|
+
if (!panel || !panel.canOrient) return;
|
|
18410
|
+
controller.styleTexts({ orientation }, { ids: panel.ids });
|
|
18411
|
+
}
|
|
18342
18412
|
|
|
18343
18413
|
// src/vector/symbolsPanel.ts
|
|
18344
18414
|
var fmt3 = (n2) => Math.round(n2 * 100) / 100;
|
|
@@ -18627,6 +18697,7 @@ export {
|
|
|
18627
18697
|
applyVectorGradientSpread,
|
|
18628
18698
|
applyHomography as applyVectorHomography,
|
|
18629
18699
|
applyVectorParagraphStyle,
|
|
18700
|
+
applyVectorTextOrientation,
|
|
18630
18701
|
applyVectorTextStyle,
|
|
18631
18702
|
arrowheadInset,
|
|
18632
18703
|
arrowheadPath,
|
|
@@ -19156,6 +19227,7 @@ export {
|
|
|
19156
19227
|
vectorTextHasOutlines,
|
|
19157
19228
|
vectorTextIndexAt,
|
|
19158
19229
|
vectorTextName,
|
|
19230
|
+
vectorTextOrientation,
|
|
19159
19231
|
vectorTextPaintSource,
|
|
19160
19232
|
vectorTextPaths,
|
|
19161
19233
|
vectorTextRange,
|
package/dist/vector/text.d.cts
CHANGED
|
@@ -29,7 +29,7 @@ export declare function vectorTextHasOutlines(): boolean;
|
|
|
29
29
|
export declare function vectorTextFamilies(): string[];
|
|
30
30
|
export declare const DEFAULT_VECTOR_FONT: Readonly<VectorCharacterStyle>;
|
|
31
31
|
/** Character style fields, in the order agents see them. */
|
|
32
|
-
export declare const VECTOR_CHARACTER_STYLE_KEYS: readonly ["fontFamily", "fontWeight", "italic", "fontSize", "tracking", "leading", "baselineShift", "underline", "strikethrough"];
|
|
32
|
+
export declare const VECTOR_CHARACTER_STYLE_KEYS: readonly ["fontFamily", "fontWeight", "italic", "fontSize", "tracking", "leading", "baselineShift", "underline", "strikethrough", "upright"];
|
|
33
33
|
/** Paragraph style fields. */
|
|
34
34
|
export declare const VECTOR_PARAGRAPH_STYLE_KEYS: readonly ["align", "autoLeading", "firstLineIndent", "startIndent", "endIndent", "spaceBefore", "spaceAfter"];
|
|
35
35
|
export declare class VectorTextError extends Error {
|
|
@@ -115,7 +115,7 @@ export interface VectorTextLayout {
|
|
|
115
115
|
shaper: string;
|
|
116
116
|
glyphs: VectorTextGlyph[];
|
|
117
117
|
fragments: VectorTextFragment[];
|
|
118
|
-
/** Lines: their text range and baseline (node space for point and area text). */
|
|
118
|
+
/** Lines: their text range and baseline (node space for point and area text; for vertical text `baseline` is a column's centre x and `x` its top y). */
|
|
119
119
|
lines: {
|
|
120
120
|
start: number;
|
|
121
121
|
end: number;
|
|
@@ -183,8 +183,10 @@ export declare function patchVectorParagraphStyle(base: VectorParagraphStyle, pa
|
|
|
183
183
|
export declare function sanitizeVectorTextFrame(value: unknown, path?: string): VectorTextFrame;
|
|
184
184
|
/** Normalised runs: fitted to the text, empty overrides dropped, `null` when there is one plain style. */
|
|
185
185
|
export declare function normalizeVectorTextRuns(text: string, runs: readonly VectorTextRun[] | null | undefined): VectorTextRun[] | null;
|
|
186
|
+
/** An orientation from loose input: `horizontal` (returned as undefined, the default) or `vertical`. */
|
|
187
|
+
export declare function vectorTextOrientation(value: unknown, path?: string): 'vertical' | undefined;
|
|
186
188
|
/** A text node read from untrusted data (JSON, SVG data attributes, agents): fields validated and normalised. */
|
|
187
|
-
export declare function sanitizeVectorTextFields(value: Record<string, unknown>): Pick<VectorTextNode, 'text' | 'font' | 'runs' | 'paragraph' | 'frame'>;
|
|
189
|
+
export declare function sanitizeVectorTextFields(value: Record<string, unknown>): Pick<VectorTextNode, 'text' | 'font' | 'runs' | 'paragraph' | 'frame' | 'orientation'>;
|
|
188
190
|
/** A range of the text from loose input: [start, end) in UTF-16 code units (default the whole text). */
|
|
189
191
|
export declare function vectorTextRange(text: string, start: unknown, end: unknown): [number, number];
|
|
190
192
|
/** The node with [start, end) of its text replaced by `insert` (styled like the character before it). */
|
package/dist/vector/text.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export declare function vectorTextHasOutlines(): boolean;
|
|
|
29
29
|
export declare function vectorTextFamilies(): string[];
|
|
30
30
|
export declare const DEFAULT_VECTOR_FONT: Readonly<VectorCharacterStyle>;
|
|
31
31
|
/** Character style fields, in the order agents see them. */
|
|
32
|
-
export declare const VECTOR_CHARACTER_STYLE_KEYS: readonly ["fontFamily", "fontWeight", "italic", "fontSize", "tracking", "leading", "baselineShift", "underline", "strikethrough"];
|
|
32
|
+
export declare const VECTOR_CHARACTER_STYLE_KEYS: readonly ["fontFamily", "fontWeight", "italic", "fontSize", "tracking", "leading", "baselineShift", "underline", "strikethrough", "upright"];
|
|
33
33
|
/** Paragraph style fields. */
|
|
34
34
|
export declare const VECTOR_PARAGRAPH_STYLE_KEYS: readonly ["align", "autoLeading", "firstLineIndent", "startIndent", "endIndent", "spaceBefore", "spaceAfter"];
|
|
35
35
|
export declare class VectorTextError extends Error {
|
|
@@ -115,7 +115,7 @@ export interface VectorTextLayout {
|
|
|
115
115
|
shaper: string;
|
|
116
116
|
glyphs: VectorTextGlyph[];
|
|
117
117
|
fragments: VectorTextFragment[];
|
|
118
|
-
/** Lines: their text range and baseline (node space for point and area text). */
|
|
118
|
+
/** Lines: their text range and baseline (node space for point and area text; for vertical text `baseline` is a column's centre x and `x` its top y). */
|
|
119
119
|
lines: {
|
|
120
120
|
start: number;
|
|
121
121
|
end: number;
|
|
@@ -183,8 +183,10 @@ export declare function patchVectorParagraphStyle(base: VectorParagraphStyle, pa
|
|
|
183
183
|
export declare function sanitizeVectorTextFrame(value: unknown, path?: string): VectorTextFrame;
|
|
184
184
|
/** Normalised runs: fitted to the text, empty overrides dropped, `null` when there is one plain style. */
|
|
185
185
|
export declare function normalizeVectorTextRuns(text: string, runs: readonly VectorTextRun[] | null | undefined): VectorTextRun[] | null;
|
|
186
|
+
/** An orientation from loose input: `horizontal` (returned as undefined, the default) or `vertical`. */
|
|
187
|
+
export declare function vectorTextOrientation(value: unknown, path?: string): 'vertical' | undefined;
|
|
186
188
|
/** A text node read from untrusted data (JSON, SVG data attributes, agents): fields validated and normalised. */
|
|
187
|
-
export declare function sanitizeVectorTextFields(value: Record<string, unknown>): Pick<VectorTextNode, 'text' | 'font' | 'runs' | 'paragraph' | 'frame'>;
|
|
189
|
+
export declare function sanitizeVectorTextFields(value: Record<string, unknown>): Pick<VectorTextNode, 'text' | 'font' | 'runs' | 'paragraph' | 'frame' | 'orientation'>;
|
|
188
190
|
/** A range of the text from loose input: [start, end) in UTF-16 code units (default the whole text). */
|
|
189
191
|
export declare function vectorTextRange(text: string, start: unknown, end: unknown): [number, number];
|
|
190
192
|
/** The node with [start, end) of its text replaced by `insert` (styled like the character before it). */
|
|
@@ -17,6 +17,10 @@ export interface VectorTextPanelData {
|
|
|
17
17
|
align: VectorTextAlign | null;
|
|
18
18
|
/** The frame kind of a single text node. */
|
|
19
19
|
frame: 'point' | 'area' | 'path' | null;
|
|
20
|
+
/** The orientation of the text edited (`null` when it mixes, or for new text). */
|
|
21
|
+
orientation: 'horizontal' | 'vertical' | null;
|
|
22
|
+
/** Whether the text edited can turn vertical (none of it is on a path). */
|
|
23
|
+
canOrient: boolean;
|
|
20
24
|
/** Families the shaper can draw (always the generic ones too). */
|
|
21
25
|
families: string[];
|
|
22
26
|
/** Whether the shaper gives outlines (Create Outlines works). */
|
|
@@ -52,3 +56,5 @@ export declare function applyVectorParagraphStyle(controller: VectorEditorContro
|
|
|
52
56
|
} & Record<string, unknown>, options?: {
|
|
53
57
|
merge?: string;
|
|
54
58
|
}): void;
|
|
59
|
+
/** Sets the text being edited or selected horizontal or vertical (one undo step); nothing for new-text defaults or path text. */
|
|
60
|
+
export declare function applyVectorTextOrientation(controller: VectorEditorController, orientation: 'horizontal' | 'vertical'): void;
|
|
@@ -17,6 +17,10 @@ export interface VectorTextPanelData {
|
|
|
17
17
|
align: VectorTextAlign | null;
|
|
18
18
|
/** The frame kind of a single text node. */
|
|
19
19
|
frame: 'point' | 'area' | 'path' | null;
|
|
20
|
+
/** The orientation of the text edited (`null` when it mixes, or for new text). */
|
|
21
|
+
orientation: 'horizontal' | 'vertical' | null;
|
|
22
|
+
/** Whether the text edited can turn vertical (none of it is on a path). */
|
|
23
|
+
canOrient: boolean;
|
|
20
24
|
/** Families the shaper can draw (always the generic ones too). */
|
|
21
25
|
families: string[];
|
|
22
26
|
/** Whether the shaper gives outlines (Create Outlines works). */
|
|
@@ -52,3 +56,5 @@ export declare function applyVectorParagraphStyle(controller: VectorEditorContro
|
|
|
52
56
|
} & Record<string, unknown>, options?: {
|
|
53
57
|
merge?: string;
|
|
54
58
|
}): void;
|
|
59
|
+
/** Sets the text being edited or selected horizontal or vertical (one undo step); nothing for new-text defaults or path text. */
|
|
60
|
+
export declare function applyVectorTextOrientation(controller: VectorEditorController, orientation: 'horizontal' | 'vertical'): void;
|
package/dist/vector/types.d.cts
CHANGED
|
@@ -620,6 +620,8 @@ export interface VectorCharacterStyle {
|
|
|
620
620
|
baselineShift?: number;
|
|
621
621
|
underline?: boolean;
|
|
622
622
|
strikethrough?: boolean;
|
|
623
|
+
/** Vertical text only: Latin and other horizontal scripts stand upright instead of turned sideways (default false). */
|
|
624
|
+
upright?: boolean;
|
|
623
625
|
}
|
|
624
626
|
/** Character style fields a run can set over the node's own style, plus its own fill. */
|
|
625
627
|
export type VectorTextRunStyle = Partial<VectorCharacterStyle> & {
|
|
@@ -695,6 +697,13 @@ export interface VectorTextNode extends VectorNodeBase, VectorStyle {
|
|
|
695
697
|
runs?: VectorTextRun[] | null;
|
|
696
698
|
paragraph?: VectorParagraphStyle | null;
|
|
697
699
|
frame: VectorTextFrame;
|
|
700
|
+
/**
|
|
701
|
+
* Missing = horizontal. `vertical` (point and area text): columns running down, stacked right to
|
|
702
|
+
* left; point text starts at the top of the first column's centre line, area text fills its box
|
|
703
|
+
* from the right edge. CJK characters stand upright, others turn sideways (unless `upright`).
|
|
704
|
+
* Text on a path ignores it.
|
|
705
|
+
*/
|
|
706
|
+
orientation?: 'vertical';
|
|
698
707
|
}
|
|
699
708
|
/**
|
|
700
709
|
* Per-instance changes to a symbol's art: every fill and / or stroke of the art painted with one
|
package/dist/vector/types.d.ts
CHANGED
|
@@ -620,6 +620,8 @@ export interface VectorCharacterStyle {
|
|
|
620
620
|
baselineShift?: number;
|
|
621
621
|
underline?: boolean;
|
|
622
622
|
strikethrough?: boolean;
|
|
623
|
+
/** Vertical text only: Latin and other horizontal scripts stand upright instead of turned sideways (default false). */
|
|
624
|
+
upright?: boolean;
|
|
623
625
|
}
|
|
624
626
|
/** Character style fields a run can set over the node's own style, plus its own fill. */
|
|
625
627
|
export type VectorTextRunStyle = Partial<VectorCharacterStyle> & {
|
|
@@ -695,6 +697,13 @@ export interface VectorTextNode extends VectorNodeBase, VectorStyle {
|
|
|
695
697
|
runs?: VectorTextRun[] | null;
|
|
696
698
|
paragraph?: VectorParagraphStyle | null;
|
|
697
699
|
frame: VectorTextFrame;
|
|
700
|
+
/**
|
|
701
|
+
* Missing = horizontal. `vertical` (point and area text): columns running down, stacked right to
|
|
702
|
+
* left; point text starts at the top of the first column's centre line, area text fills its box
|
|
703
|
+
* from the right edge. CJK characters stand upright, others turn sideways (unless `upright`).
|
|
704
|
+
* Text on a path ignores it.
|
|
705
|
+
*/
|
|
706
|
+
orientation?: 'vertical';
|
|
698
707
|
}
|
|
699
708
|
/**
|
|
700
709
|
* Per-instance changes to a symbol's art: every fill and / or stroke of the art painted with one
|
package/package.json
CHANGED
|
@@ -301,13 +301,14 @@ in the source frame at the document's bit depth, colour mode and profile. Read
|
|
|
301
301
|
| `remove_layer_mask` | Delete a mask without applying it; disable it instead to keep it. |
|
|
302
302
|
| `layer_via_copy` | Copy the selected pixels of a pixel layer (default the active one) to a new layer above it; `cut: true` removes them from the source. Needs a selection. Returns the new layer. |
|
|
303
303
|
| `rasterize_layer` | Turn a shape layer into a pixel layer showing the same pixels (same id, mask, effects, opacity, blend; the paths are gone), an annotation layer into pixels (browser only), a smart object into a pixel layer (as `rasterize_smart_object`), or bake a pixel layer's develop / blur filters into its pixels. Do it before painting over a shape or annotation, or when the user wants the filters fixed. Destructive. |
|
|
304
|
-
| `add_text_layer` | Add live type above the active layer and make it active: `text`, `x`, `y`, optional `box` (paragraph text), `style`, `paragraph`, `rotation`, `name`, `opacity`, `blend`, placement. Returns the `layer` and `text` (with `lines` and `missingFonts`). One undo step. |
|
|
304
|
+
| `add_text_layer` | Add live type above the active layer and make it active: `text`, `x`, `y`, optional `box` (paragraph text), `orientation` (`vertical`: columns down from `x`, `y`, right to left, for Japanese / Chinese / Korean), `style`, `paragraph`, `rotation`, `name`, `opacity`, `blend`, placement. Returns the `layer` and `text` (with `orientation`, `lines` and `missingFonts`). One undo step. |
|
|
305
305
|
| `set_text` | Replace text `start`..`end` (default all) with `text`; start = end inserts. New text takes the style at `start`. Returns the text layer. |
|
|
306
|
-
| `set_text_style` | Set character style fields over `start`..`end` (default all): `fontFamily`, `fontWeight`, `italic`, `fontSize`, `color`, `opacity`, `tracking`, `leading`, `baselineShift`, `underline`, `strikethrough` (`null` resets optional ones). Returns the runs. |
|
|
306
|
+
| `set_text_style` | Set character style fields over `start`..`end` (default all): `fontFamily`, `fontWeight`, `italic`, `fontSize`, `color`, `opacity`, `tracking`, `leading`, `baselineShift`, `underline`, `strikethrough`, `upright` (vertical text: Latin upright instead of turned) (`null` resets optional ones). Returns the runs. |
|
|
307
307
|
| `set_paragraph_style` | Set `align`, `autoLeading`, indents, `spaceBefore` / `spaceAfter` on every paragraph `start`..`end` touches (default all). Returns the text layer. |
|
|
308
308
|
| `set_text_frame` | `kind: point` (one line per paragraph) or `kind: box` with `width` and `height` (wrapping paragraph text), or resize a box; the first line stays put. Returns the text layer and its lines. |
|
|
309
|
+
| `set_text_orientation` | Type › Orientation: `horizontal` or `vertical` (columns top to bottom, right to left; CJK upright, Latin turned sideways unless `upright`). Text, styles, frame and origin stay. Returns the text layer with its new lines (columns). One undo step. |
|
|
309
310
|
| `convert_text_to_shape` | Type › Convert to Shape: glyph outlines become a shape layer with the same id (text no longer editable; fill from the first run's colour; `warnings` lists losses). Needs an outline font shaper. Destructive. |
|
|
310
|
-
| `select_text_shape` | Horizontal / Vertical Type Mask: select the shape of `text` at `x`, `y` (style, box, rotation as `add_text_layer`; `orientation` `vertical`
|
|
311
|
+
| `select_text_shape` | Horizontal / Vertical Type Mask: select the shape of `text` at `x`, `y` (style, box, rotation as `add_text_layer`; `orientation` `vertical` lays it out as vertical type: columns down from `x`, `y`, right to left, CJK upright, Latin turned), by `mode`, with `feather`. No layer is added. Returns the selection. |
|
|
311
312
|
| `add_shape_layer` | Add a vector shape layer above the active layer (or placed with `aboveId` / `belowId` / `parentId` / `index`) and make it active: `shape` (live rect, ellipse, polygon, star or line, document px), `subpaths` (SVG path data or anchors) or several `components` with path ops; `fill` (colour, gradient or pattern, default the foreground colour; `null` none), `stroke` (`width`, `paint`, `align`, `cap`, `join`, `miterLimit`, `dashes` in widths), `fillRule`, `name`, `opacity`, `blend`. Returns the `layer` and the `shape`. One undo step. |
|
|
312
313
|
| `update_shape` | Restyle a shape: `fill` (replace, `null` removes), `stroke` (only the settings given change; `null` removes; a new stroke needs `width` and `paint`), `fillRule`. Geometry is unchanged. Returns the shape. |
|
|
313
314
|
| `set_shape_component` | Change component `componentIndex` (from `get_shape_layer`): `shape` fields (without `kind`, or with the same kind, unset fields keep their values), new `subpaths` (ends the live shape), or `op`. Returns the shape. |
|
|
@@ -20,7 +20,7 @@ Detail for the `pixerate-image-editor` skill: how to draw and edit vector shapes
|
|
|
20
20
|
`x2` / `y2`, …; the rest stay), replaces a component's `subpaths` (ending its live shape) or
|
|
21
21
|
changes its `op`. `update_shape` restyles the fill, the stroke (only the settings given) or the
|
|
22
22
|
fill rule. Read `get_shape_layer` first for the component indices.
|
|
23
|
-
|
|
23
|
+
5. **Place it**: `offset_layer`, `transform_layer`, `flip_layer`, `rotate_layer_90` and `warp_layer`
|
|
24
24
|
map the paths, never resample pixels; live shapes stay live under moves, scales, rotations and
|
|
25
25
|
skews (perspective and warps turn them into plain paths). Stroke widths do not scale.
|
|
26
26
|
5. **Style it like any layer**: masks, clipping, blend modes, opacity, fill opacity and layer
|
|
@@ -36,18 +36,29 @@ Detail for the `pixerate-image-editor` skill: how to draw and edit vector shapes
|
|
|
36
36
|
`italic`, `fontSize` in px, `color`, `tracking` in 1/1000 em, `leading` in px, `baselineShift`,
|
|
37
37
|
`underline`, `strikethrough`) and a `paragraph` style (`align`, `autoLeading`, indents,
|
|
38
38
|
`spaceBefore` / `spaceAfter`). Call `list_fonts` first when the font matters: a missing family
|
|
39
|
-
draws with a fallback and comes back in `missingFonts`.
|
|
39
|
+
draws with a fallback and comes back in `missingFonts`. For Japanese, Chinese or Korean set in
|
|
40
|
+
columns pass `orientation: "vertical"` (or switch later with `set_text_orientation`): columns
|
|
41
|
+
run down from (`x`, `y`), the top of the first column's centre line, and stack right to left;
|
|
42
|
+
a vertical `box` fills from its right edge and wraps at its height.
|
|
40
43
|
2. **Edit by range**: ranges are `start` / `end` in UTF-16 code units, `end` exclusive, as
|
|
41
44
|
`get_text_layer` reports runs and lines. `set_text` replaces a range (start = end inserts; new
|
|
42
45
|
text takes the style at `start`), `set_text_style` styles a range (only the fields given),
|
|
43
46
|
`set_paragraph_style` styles the paragraphs a range touches. Re-read the runs after an edit
|
|
44
47
|
that changes the length before using old ranges.
|
|
45
48
|
3. **Shape the block**: `set_text_frame` switches between point text and a wrapping box (or
|
|
46
|
-
resizes the box) with the first line kept in place.
|
|
49
|
+
resizes the box) with the first line kept in place (vertically, the first column's top-right).
|
|
50
|
+
4. **Vertical text**: ideographs, kana and Hangul stand upright; Latin, digits and spaces turn
|
|
51
|
+
90° clockwise, which suits words inside Japanese text. For short Latin or acronyms that should
|
|
52
|
+
read down letter by letter, set `upright: true` on that range with `set_text_style`. Brackets,
|
|
53
|
+
dashes and 、。 use the font's vertical forms when the shaper reads them (an outline shaper over
|
|
54
|
+
an OpenType font with `vert`); the browser canvas turns brackets and moves 、。 to the upper
|
|
55
|
+
right instead. In `get_text_layer`, `lines` are columns: `baseline` is a column's centre in
|
|
56
|
+
line space, not a y. Use a font with CJK glyphs (`list_fonts`): a Latin-only family draws CJK
|
|
57
|
+
with a fallback.
|
|
47
58
|
4. **Place it**: `offset_layer`, `transform_layer`, `flip_layer` and `rotate_layer_90` change the
|
|
48
59
|
text's matrix and draw it again (scale, rotate, skew, flips). Distort, perspective and warp are
|
|
49
60
|
refused: rasterize first. Masks, clipping, blend modes and effects work as on any layer.
|
|
50
|
-
|
|
61
|
+
6. **Outlines and pixels**: `convert_text_to_shape` makes glyph outlines a shape layer (needs an
|
|
51
62
|
outline font shaper; the browser canvas cannot); `rasterize_layer` makes it pixels.
|
|
52
63
|
For a selection in the shape of text (photo-filled letters, text cut out of the image) use
|
|
53
64
|
`select_text_shape`, the Type Mask: it lays the text out the same way but adds no layer.
|
|
@@ -56,7 +67,8 @@ Detail for the `pixerate-image-editor` skill: how to draw and edit vector shapes
|
|
|
56
67
|
|
|
57
68
|
`import_psd` brings Photoshop shape layers in as live shapes (paths with their path operations, fill,
|
|
58
69
|
stroke, and live rectangles, rounded rectangles, ellipses and lines) and type layers as live text
|
|
59
|
-
that shows Photoshop's pixels until it is edited
|
|
70
|
+
that shows Photoshop's pixels until it is edited; vertical type comes in vertical (with its
|
|
71
|
+
upright-Latin runs) and goes back out as vertical type. `get_text_layer` reports `rendering: "stored"`
|
|
60
72
|
and `missingFonts` for those: if a font is missing, edits draw with a fallback, so tell the user
|
|
61
73
|
before editing such text, or pick an available font with `set_text_style`. `export_psd` writes both
|
|
62
74
|
kinds back as Photoshop layers; unchanged ones are written byte for byte as they were read.
|
|
@@ -106,6 +106,11 @@ Parameter details (gradient fields, effect parameters, width profiles, envelopes
|
|
|
106
106
|
than splitting text into separate nodes, so it still edits as one paragraph. Create Outlines
|
|
107
107
|
only for final artwork or logos that must not depend on fonts; keep a copy as text if it may
|
|
108
108
|
change.
|
|
109
|
+
For Japanese, Chinese or Korean set in columns (signage, book spines, posters), use vertical
|
|
110
|
+
text (`textOrientation: "vertical"` or `vector.setTextOrientation`): CJK stands upright, Latin
|
|
111
|
+
turns sideways; set a short Latin range `upright: true` to stack it letter by letter. In an
|
|
112
|
+
area, columns that do not fit past the left edge are `overflow`. Vertical text cannot follow a
|
|
113
|
+
path.
|
|
109
114
|
|
|
110
115
|
- **Clean paths.** Use the fewest anchors that describe the shape: anchors at extrema (top,
|
|
111
116
|
bottom, left, right of a curve) and at true corners, handles horizontal or vertical at extrema,
|
|
@@ -260,12 +265,13 @@ arrays, to build or replace a stack in one call.
|
|
|
260
265
|
| Command | Use it to |
|
|
261
266
|
| --- | --- |
|
|
262
267
|
| `vector.listFonts` | See which families the text shaper can draw and whether it gives glyph outlines (`outlines`); read it before choosing fonts or calling `vector.createOutlines`. Returns `{ shaper, outlines, families }`. |
|
|
263
|
-
| `vector.addText` | Add point text (`x`, `y`: the first baseline's start), area text (`x`, `y`, `width`, `height`: wrapped in the box) or text along `path` (SVG path data, with `start`, `end`, `flip`, `orientation`, `baseline`). `font`, `paragraph`, `name`, `fill`, `stroke`, `strokeWidth` optional; black, no stroke by default. Returns the text summary (`id`, lines, bounds, overflow). |
|
|
264
|
-
| `vector.getText` | Read a text node: text, base font, runs as `{ start, end, style }`, paragraph, frame, fill, stroke, laid-out lines, document bounds, `overflow`, `outlines`, shaper and missing fonts. Call before editing ranges. |
|
|
268
|
+
| `vector.addText` | Add point text (`x`, `y`: the first baseline's start), area text (`x`, `y`, `width`, `height`: wrapped in the box) or text along `path` (SVG path data, with `start`, `end`, `flip`, `orientation`, `baseline`). `textOrientation: "vertical"` sets point or area text in columns down and right to left (`x`, `y` the top of the first column's centre; an area fills from its right edge). `font`, `paragraph`, `name`, `fill`, `stroke`, `strokeWidth` optional; black, no stroke by default. Returns the text summary (`id`, `orientation`, lines, bounds, overflow). |
|
|
269
|
+
| `vector.getText` | Read a text node: text, base font, runs as `{ start, end, style }`, paragraph, frame, `orientation`, fill, stroke, laid-out lines, document bounds, `overflow`, `outlines`, shaper and missing fonts. Call before editing ranges. |
|
|
265
270
|
| `vector.setText` | Replace `[start, end)` of the text with `text` (default the whole text; `start` = `end` inserts, `""` deletes). Inserted characters take the style before them. Returns the summary. |
|
|
266
|
-
| `vector.setTextStyle` | Set character fields (`fontFamily`, `fontWeight`, `italic`, `fontSize`, `tracking`, `leading`, `baselineShift`, `underline`, `strikethrough
|
|
271
|
+
| `vector.setTextStyle` | Set character fields (`fontFamily`, `fontWeight`, `italic`, `fontSize`, `tracking`, `leading`, `baselineShift`, `underline`, `strikethrough`, `upright` for Latin standing upright in vertical text; null clears) and `fill` over `[start, end)`; the whole text (default) changes the base font and the node's fill. Returns the summary with runs. |
|
|
267
272
|
| `vector.setParagraphStyle` | Set `align` (left, center, right, justify), `autoLeading`, indents and spacing for the node's paragraphs. Returns the summary. |
|
|
268
273
|
| `vector.setTextFrame` | Switch between point, area and path text (`kind`), resize an area (`width`, `height`), move the origin (`x`, `y`) or change path options. Returns the summary. |
|
|
274
|
+
| `vector.setTextOrientation` | Set point or area text `horizontal` or `vertical` (columns top to bottom, right to left; CJK upright, Latin turned sideways unless `upright`). Text on a path cannot be vertical. Returns the summary. |
|
|
269
275
|
| `vector.typeOnPath` | Turn path node `pathId` into text along it (it takes the path's place and drops its paint) with `text`, `font`, `paragraph` (`align` places it along the path) and path options. Returns the summary with the new id. |
|
|
270
276
|
| `vector.createOutlines` | Turn text (`ids`, or text inside groups; default the selection) into paths of its glyph outlines, keeping paint, effects, filters, placement and id. Needs `outlines: true` from `vector.listFonts`. Returns `{ ids }`. |
|
|
271
277
|
|