@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
|
@@ -1061,6 +1061,59 @@ function gposKerning(view, t) {
|
|
|
1061
1061
|
return 0;
|
|
1062
1062
|
};
|
|
1063
1063
|
}
|
|
1064
|
+
function coverageGlyphs(view, at) {
|
|
1065
|
+
const format = view.getUint16(at);
|
|
1066
|
+
const n = view.getUint16(at + 2);
|
|
1067
|
+
const out = [];
|
|
1068
|
+
if (format === 1) for (let i = 0; i < n; i++) out.push(view.getUint16(at + 4 + i * 2));
|
|
1069
|
+
else if (format === 2)
|
|
1070
|
+
for (let i = 0; i < n; i++) {
|
|
1071
|
+
const r = at + 4 + i * 6;
|
|
1072
|
+
for (let g = view.getUint16(r); g <= view.getUint16(r + 2); g++) out.push(g);
|
|
1073
|
+
}
|
|
1074
|
+
return out;
|
|
1075
|
+
}
|
|
1076
|
+
function gsubVertical(view, t) {
|
|
1077
|
+
const out = /* @__PURE__ */ new Map();
|
|
1078
|
+
if (!t || t.length < 10) return out;
|
|
1079
|
+
const base = t.offset;
|
|
1080
|
+
const features = base + view.getUint16(base + 6);
|
|
1081
|
+
const lookups = base + view.getUint16(base + 8);
|
|
1082
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1083
|
+
const nf = view.getUint16(features);
|
|
1084
|
+
for (let i = 0; i < nf; i++) {
|
|
1085
|
+
const rec = features + 2 + i * 6;
|
|
1086
|
+
let tag = "";
|
|
1087
|
+
for (let k = 0; k < 4; k++) tag += String.fromCharCode(view.getUint8(rec + k));
|
|
1088
|
+
if (tag !== "vert") continue;
|
|
1089
|
+
const f = features + view.getUint16(rec + 4);
|
|
1090
|
+
const n = view.getUint16(f + 2);
|
|
1091
|
+
for (let k = 0; k < n; k++) ids.add(view.getUint16(f + 4 + k * 2));
|
|
1092
|
+
}
|
|
1093
|
+
const nl = view.getUint16(lookups);
|
|
1094
|
+
for (const id of [...ids].sort((a, b) => a - b)) {
|
|
1095
|
+
if (id >= nl) continue;
|
|
1096
|
+
const l = lookups + view.getUint16(lookups + 2 + id * 2);
|
|
1097
|
+
const n = view.getUint16(l + 4);
|
|
1098
|
+
for (let k = 0; k < n; k++) {
|
|
1099
|
+
let type = view.getUint16(l);
|
|
1100
|
+
let st = l + view.getUint16(l + 6 + k * 2);
|
|
1101
|
+
if (type === 7) {
|
|
1102
|
+
type = view.getUint16(st + 2);
|
|
1103
|
+
st = st + view.getUint32(st + 4);
|
|
1104
|
+
}
|
|
1105
|
+
if (type !== 1) continue;
|
|
1106
|
+
const format = view.getUint16(st);
|
|
1107
|
+
const glyphs = coverageGlyphs(view, st + view.getUint16(st + 2));
|
|
1108
|
+
glyphs.forEach((g, i) => {
|
|
1109
|
+
if (out.has(g)) return;
|
|
1110
|
+
if (format === 1) out.set(g, (g + view.getInt16(st + 4) + 65536) % 65536);
|
|
1111
|
+
else if (format === 2 && i < view.getUint16(st + 4)) out.set(g, view.getUint16(st + 6 + i * 2));
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
return out;
|
|
1116
|
+
}
|
|
1064
1117
|
var toView = (data) => data instanceof ArrayBuffer ? new DataView(data) : new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
1065
1118
|
function parseOpenTypeFont(data, options = {}) {
|
|
1066
1119
|
const view = toView(data);
|
|
@@ -1125,6 +1178,12 @@ function parseOpenTypeFont(data, options = {}) {
|
|
|
1125
1178
|
if (i >= 0 && hmtx.offset + i * 4 + 2 <= hmtx.offset + hmtx.length) return view.getUint16(hmtx.offset + i * 4);
|
|
1126
1179
|
return cffWidth?.(g) ?? 0;
|
|
1127
1180
|
};
|
|
1181
|
+
const vhea = tables.get("vhea");
|
|
1182
|
+
const vmtx = tables.get("vmtx");
|
|
1183
|
+
const numVMetrics = vhea && vhea.length >= 36 ? view.getUint16(vhea.offset + 34) : 0;
|
|
1184
|
+
const hasVerticalMetrics = Boolean(vmtx && numVMetrics > 0);
|
|
1185
|
+
const vorg = tables.get("VORG");
|
|
1186
|
+
const vertSub = gsubVertical(view, tables.get("GSUB"));
|
|
1128
1187
|
const kernPairs = readKern(view, tables.get("kern"));
|
|
1129
1188
|
const gpos = gposKerning(view, tables.get("GPOS"));
|
|
1130
1189
|
const kerning = (a, b) => (gpos ? gpos(a, b) : 0) || kernPairs.get(a * 65536 + b) || 0;
|
|
@@ -1139,17 +1198,43 @@ function parseOpenTypeFont(data, options = {}) {
|
|
|
1139
1198
|
}
|
|
1140
1199
|
return p;
|
|
1141
1200
|
};
|
|
1142
|
-
const
|
|
1201
|
+
const verticalGlyph = (g) => vertSub.get(g) ?? g;
|
|
1202
|
+
const vertOrigin = (g) => {
|
|
1203
|
+
if (vorg && vorg.length >= 8) {
|
|
1204
|
+
const n = view.getUint16(vorg.offset + 6);
|
|
1205
|
+
let lo = 0;
|
|
1206
|
+
let hi = n - 1;
|
|
1207
|
+
while (lo <= hi) {
|
|
1208
|
+
const mid = lo + hi >> 1;
|
|
1209
|
+
const at2 = vorg.offset + 8 + mid * 4;
|
|
1210
|
+
const v = view.getUint16(at2);
|
|
1211
|
+
if (v === g) return view.getInt16(at2 + 2);
|
|
1212
|
+
if (v < g) lo = mid + 1;
|
|
1213
|
+
else hi = mid - 1;
|
|
1214
|
+
}
|
|
1215
|
+
return view.getInt16(vorg.offset + 4);
|
|
1216
|
+
}
|
|
1217
|
+
if (!hasVerticalMetrics) return ascender;
|
|
1218
|
+
const tsb = g < numVMetrics ? view.getInt16(vmtx.offset + g * 4 + 2) : view.getInt16(vmtx.offset + numVMetrics * 4 + (g - numVMetrics) * 2);
|
|
1219
|
+
let top = -Infinity;
|
|
1220
|
+
for (const c of glyphPath(g)) for (const v of [c.y, c.y1, c.y2]) if (v !== void 0 && v > top) top = v;
|
|
1221
|
+
return Number.isFinite(top) ? top + tsb : ascender;
|
|
1222
|
+
};
|
|
1223
|
+
const verticalAdvance = (g) => {
|
|
1224
|
+
if (!hasVerticalMetrics || g < 0 || g >= numGlyphs) return ascender - descender;
|
|
1225
|
+
return view.getUint16(vmtx.offset + Math.min(g, numVMetrics - 1) * 4);
|
|
1226
|
+
};
|
|
1227
|
+
const glyphs = (text, vertical = false) => {
|
|
1143
1228
|
const out = [];
|
|
1144
1229
|
for (const ch of text) {
|
|
1145
1230
|
const cp = ch.codePointAt(0);
|
|
1146
1231
|
if (cp >= 55296 && cp <= 57343 || cp === 10 || cp === 13) continue;
|
|
1147
|
-
out.push(glyphIndex(cp));
|
|
1232
|
+
out.push(vertical ? verticalGlyph(glyphIndex(cp)) : glyphIndex(cp));
|
|
1148
1233
|
}
|
|
1149
1234
|
return out;
|
|
1150
1235
|
};
|
|
1151
|
-
const layout = (text, kern) => {
|
|
1152
|
-
const gs = glyphs(text);
|
|
1236
|
+
const layout = (text, kern, vertical = false) => {
|
|
1237
|
+
const gs = glyphs(text, vertical);
|
|
1153
1238
|
const xs = [];
|
|
1154
1239
|
let x = 0;
|
|
1155
1240
|
for (let i = 0; i < gs.length; i++) {
|
|
@@ -1176,12 +1261,19 @@ function parseOpenTypeFont(data, options = {}) {
|
|
|
1176
1261
|
advance,
|
|
1177
1262
|
kerning,
|
|
1178
1263
|
glyphPath,
|
|
1264
|
+
hasVerticalMetrics,
|
|
1265
|
+
verticalGlyph,
|
|
1266
|
+
getVerticalMetrics(char) {
|
|
1267
|
+
const g = glyphIndex(char.codePointAt(0) ?? 0);
|
|
1268
|
+
const v = verticalGlyph(g);
|
|
1269
|
+
return { advance: verticalAdvance(v), originY: vertOrigin(v), alternate: v !== g };
|
|
1270
|
+
},
|
|
1179
1271
|
getAdvanceWidth(text, fontSize, opts) {
|
|
1180
1272
|
return layout(text, opts?.kerning !== false).width * fontSize / unitsPerEm;
|
|
1181
1273
|
},
|
|
1182
1274
|
getPath(text, x, y, fontSize, opts) {
|
|
1183
1275
|
const k = fontSize / unitsPerEm;
|
|
1184
|
-
const { gs, xs } = layout(text, opts?.kerning !== false);
|
|
1276
|
+
const { gs, xs } = layout(text, opts?.kerning !== false, Boolean(opts?.vertical));
|
|
1185
1277
|
const commands = [];
|
|
1186
1278
|
gs.forEach((g, i) => {
|
|
1187
1279
|
const ox = x + xs[i] * k;
|