Merge 4fed542e3f808350cc4fdb37013b368b12778071 into a96553648551b94652f4b1139c440d53c806836f
This commit is contained in:
commit
94e48bc23b
@ -40,7 +40,11 @@ import {
|
|||||||
lookupMatrix,
|
lookupMatrix,
|
||||||
lookupNormalRect,
|
lookupNormalRect,
|
||||||
} from "./core_utils.js";
|
} from "./core_utils.js";
|
||||||
import { FontInfo, PatternInfo } from "../shared/obj-bin-transform.js";
|
import {
|
||||||
|
FontInfo,
|
||||||
|
FontPathInfo,
|
||||||
|
PatternInfo,
|
||||||
|
} from "../shared/obj-bin-transform.js";
|
||||||
import {
|
import {
|
||||||
getEncoding,
|
getEncoding,
|
||||||
MacRomanEncoding,
|
MacRomanEncoding,
|
||||||
@ -4663,11 +4667,8 @@ class PartialEvaluator {
|
|||||||
if (font.renderer.hasBuiltPath(fontChar)) {
|
if (font.renderer.hasBuiltPath(fontChar)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handler.send("commonobj", [
|
const buffer = FontPathInfo.write(font.renderer.getPathJs(fontChar));
|
||||||
glyphName,
|
handler.send("commonobj", [glyphName, "FontPath", buffer], [buffer]);
|
||||||
"FontPath",
|
|
||||||
font.renderer.getPathJs(fontChar),
|
|
||||||
]);
|
|
||||||
} catch (reason) {
|
} catch (reason) {
|
||||||
if (evaluatorOptions.ignoreErrors) {
|
if (evaluatorOptions.ignoreErrors) {
|
||||||
warn(`buildFontPaths - ignoring ${glyphName} glyph: "${reason}".`);
|
warn(`buildFontPaths - ignoring ${glyphName} glyph: "${reason}".`);
|
||||||
|
|||||||
@ -45,7 +45,11 @@ import {
|
|||||||
StatTimer,
|
StatTimer,
|
||||||
} from "./display_utils.js";
|
} from "./display_utils.js";
|
||||||
import { FontFaceObject, FontLoader } from "./font_loader.js";
|
import { FontFaceObject, FontLoader } from "./font_loader.js";
|
||||||
import { FontInfo, PatternInfo } from "../shared/obj-bin-transform.js";
|
import {
|
||||||
|
FontInfo,
|
||||||
|
FontPathInfo,
|
||||||
|
PatternInfo,
|
||||||
|
} from "../shared/obj-bin-transform.js";
|
||||||
import {
|
import {
|
||||||
getDataProp,
|
getDataProp,
|
||||||
getFactoryUrlProp,
|
getFactoryUrlProp,
|
||||||
@ -2821,6 +2825,8 @@ class WorkerTransport {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "FontPath":
|
case "FontPath":
|
||||||
|
this.commonObjs.resolve(id, new FontPathInfo(exportedData));
|
||||||
|
break;
|
||||||
case "Image":
|
case "Image":
|
||||||
this.commonObjs.resolve(id, exportedData);
|
this.commonObjs.resolve(id, exportedData);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -436,7 +436,7 @@ class FontFaceObject {
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
warn(`getPathGenerator - ignoring character: "${ex}".`);
|
warn(`getPathGenerator - ignoring character: "${ex}".`);
|
||||||
}
|
}
|
||||||
const path = makePathFromDrawOPS(cmds);
|
const path = makePathFromDrawOPS(cmds.path);
|
||||||
|
|
||||||
if (!this.fontExtraProperties) {
|
if (!this.fontExtraProperties) {
|
||||||
// Remove the raw path-string, since we don't need it anymore.
|
// Remove the raw path-string, since we don't need it anymore.
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert, MeshFigureType } from "./util.js";
|
import { assert, FeatureTest, MeshFigureType } from "./util.js";
|
||||||
|
|
||||||
class CssFontInfo {
|
class CssFontInfo {
|
||||||
#buffer;
|
#buffer;
|
||||||
@ -881,4 +881,40 @@ class PatternInfo {
|
|||||||
throw new Error(`Unsupported pattern kind: ${kind}`);
|
throw new Error(`Unsupported pattern kind: ${kind}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export { CssFontInfo, FontInfo, PatternInfo, SystemFontInfo };
|
|
||||||
|
class FontPathInfo {
|
||||||
|
static write(path) {
|
||||||
|
let data;
|
||||||
|
let buffer;
|
||||||
|
if (
|
||||||
|
(typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) ||
|
||||||
|
FeatureTest.isFloat16ArraySupported
|
||||||
|
) {
|
||||||
|
buffer = new ArrayBuffer(path.length * 2);
|
||||||
|
data = new Float16Array(buffer);
|
||||||
|
} else {
|
||||||
|
buffer = new ArrayBuffer(path.length * 4);
|
||||||
|
data = new Float32Array(buffer);
|
||||||
|
}
|
||||||
|
data.set(path);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buffer;
|
||||||
|
|
||||||
|
constructor(buffer) {
|
||||||
|
this.#buffer = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
get path() {
|
||||||
|
if (
|
||||||
|
(typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) ||
|
||||||
|
FeatureTest.isFloat16ArraySupported
|
||||||
|
) {
|
||||||
|
return new Float16Array(this.#buffer);
|
||||||
|
}
|
||||||
|
return new Float32Array(this.#buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { CssFontInfo, FontInfo, FontPathInfo, PatternInfo, SystemFontInfo };
|
||||||
|
|||||||
@ -16,437 +16,470 @@
|
|||||||
import {
|
import {
|
||||||
CssFontInfo,
|
CssFontInfo,
|
||||||
FontInfo,
|
FontInfo,
|
||||||
|
FontPathInfo,
|
||||||
PatternInfo,
|
PatternInfo,
|
||||||
SystemFontInfo,
|
SystemFontInfo,
|
||||||
} from "../../src/shared/obj-bin-transform.js";
|
} from "../../src/shared/obj-bin-transform.js";
|
||||||
import { MeshFigureType } from "../../src/shared/util.js";
|
import { FeatureTest, MeshFigureType } from "../../src/shared/util.js";
|
||||||
|
|
||||||
const cssFontInfo = {
|
describe("obj-bin-transform", function () {
|
||||||
fontFamily: "Sample Family",
|
describe("Font data", function () {
|
||||||
fontWeight: "not a number",
|
const cssFontInfo = {
|
||||||
italicAngle: "angle",
|
fontFamily: "Sample Family",
|
||||||
uselessProp: "doesn't matter",
|
fontWeight: "not a number",
|
||||||
};
|
italicAngle: "angle",
|
||||||
|
uselessProp: "doesn't matter",
|
||||||
|
};
|
||||||
|
|
||||||
const systemFontInfo = {
|
const systemFontInfo = {
|
||||||
guessFallback: false,
|
guessFallback: false,
|
||||||
css: "some string",
|
css: "some string",
|
||||||
loadedName: "another string",
|
loadedName: "another string",
|
||||||
baseFontName: "base name",
|
baseFontName: "base name",
|
||||||
src: "source",
|
src: "source",
|
||||||
style: {
|
style: {
|
||||||
style: "normal",
|
style: "normal",
|
||||||
weight: "400",
|
weight: "400",
|
||||||
uselessProp: "doesn't matter",
|
uselessProp: "doesn't matter",
|
||||||
},
|
},
|
||||||
uselessProp: "doesn't matter",
|
uselessProp: "doesn't matter",
|
||||||
};
|
};
|
||||||
|
|
||||||
const fontInfo = {
|
const fontInfo = {
|
||||||
black: true,
|
black: true,
|
||||||
bold: true,
|
bold: true,
|
||||||
disableFontFace: true,
|
disableFontFace: true,
|
||||||
fontExtraProperties: true,
|
fontExtraProperties: true,
|
||||||
isInvalidPDFjsFont: true,
|
isInvalidPDFjsFont: true,
|
||||||
isType3Font: true,
|
isType3Font: true,
|
||||||
italic: true,
|
italic: true,
|
||||||
missingFile: true,
|
missingFile: true,
|
||||||
remeasure: true,
|
remeasure: true,
|
||||||
vertical: true,
|
vertical: true,
|
||||||
ascent: 1,
|
ascent: 1,
|
||||||
defaultWidth: 1,
|
defaultWidth: 1,
|
||||||
descent: 1,
|
descent: 1,
|
||||||
bbox: [1, 1, 1, 1],
|
bbox: [1, 1, 1, 1],
|
||||||
fontMatrix: [1, 1, 1, 1, 1, 1],
|
fontMatrix: [1, 1, 1, 1, 1, 1],
|
||||||
defaultVMetrics: [1, 1, 1],
|
defaultVMetrics: [1, 1, 1],
|
||||||
fallbackName: "string",
|
fallbackName: "string",
|
||||||
loadedName: "string",
|
loadedName: "string",
|
||||||
mimetype: "string",
|
mimetype: "string",
|
||||||
name: "string",
|
name: "string",
|
||||||
data: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
|
data: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
|
||||||
uselessProp: "something",
|
uselessProp: "something",
|
||||||
};
|
};
|
||||||
|
|
||||||
describe("font data serialization and deserialization", function () {
|
describe("font data serialization and deserialization", function () {
|
||||||
describe("CssFontInfo", function () {
|
describe("CssFontInfo", function () {
|
||||||
it("must roundtrip correctly for CssFontInfo", function () {
|
it("must roundtrip correctly for CssFontInfo", function () {
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
let sizeEstimate = 0;
|
let sizeEstimate = 0;
|
||||||
for (const string of ["Sample Family", "not a number", "angle"]) {
|
for (const string of ["Sample Family", "not a number", "angle"]) {
|
||||||
sizeEstimate += 4 + encoder.encode(string).length;
|
sizeEstimate += 4 + encoder.encode(string).length;
|
||||||
}
|
}
|
||||||
const buffer = CssFontInfo.write(cssFontInfo);
|
const buffer = CssFontInfo.write(cssFontInfo);
|
||||||
expect(buffer.byteLength).toEqual(sizeEstimate);
|
expect(buffer.byteLength).toEqual(sizeEstimate);
|
||||||
const deserialized = new CssFontInfo(buffer);
|
const deserialized = new CssFontInfo(buffer);
|
||||||
expect(deserialized.fontFamily).toEqual("Sample Family");
|
expect(deserialized.fontFamily).toEqual("Sample Family");
|
||||||
expect(deserialized.fontWeight).toEqual("not a number");
|
expect(deserialized.fontWeight).toEqual("not a number");
|
||||||
expect(deserialized.italicAngle).toEqual("angle");
|
expect(deserialized.italicAngle).toEqual("angle");
|
||||||
expect(deserialized.uselessProp).toBeUndefined();
|
expect(deserialized.uselessProp).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("SystemFontInfo", function () {
|
describe("SystemFontInfo", function () {
|
||||||
it("must roundtrip correctly for SystemFontInfo", function () {
|
it("must roundtrip correctly for SystemFontInfo", function () {
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
let sizeEstimate = 1 + 4;
|
let sizeEstimate = 1 + 4;
|
||||||
for (const string of [
|
for (const string of [
|
||||||
"some string",
|
"some string",
|
||||||
"another string",
|
"another string",
|
||||||
"base name",
|
"base name",
|
||||||
"source",
|
"source",
|
||||||
"normal",
|
"normal",
|
||||||
"400",
|
"400",
|
||||||
]) {
|
]) {
|
||||||
sizeEstimate += 4 + encoder.encode(string).length;
|
sizeEstimate += 4 + encoder.encode(string).length;
|
||||||
}
|
}
|
||||||
const buffer = SystemFontInfo.write(systemFontInfo);
|
const buffer = SystemFontInfo.write(systemFontInfo);
|
||||||
expect(buffer.byteLength).toEqual(sizeEstimate);
|
expect(buffer.byteLength).toEqual(sizeEstimate);
|
||||||
const deserialized = new SystemFontInfo(buffer);
|
const deserialized = new SystemFontInfo(buffer);
|
||||||
expect(deserialized.guessFallback).toEqual(false);
|
expect(deserialized.guessFallback).toEqual(false);
|
||||||
expect(deserialized.css).toEqual("some string");
|
expect(deserialized.css).toEqual("some string");
|
||||||
expect(deserialized.loadedName).toEqual("another string");
|
expect(deserialized.loadedName).toEqual("another string");
|
||||||
expect(deserialized.baseFontName).toEqual("base name");
|
expect(deserialized.baseFontName).toEqual("base name");
|
||||||
expect(deserialized.src).toEqual("source");
|
expect(deserialized.src).toEqual("source");
|
||||||
expect(deserialized.style.style).toEqual("normal");
|
expect(deserialized.style.style).toEqual("normal");
|
||||||
expect(deserialized.style.weight).toEqual("400");
|
expect(deserialized.style.weight).toEqual("400");
|
||||||
expect(deserialized.style.uselessProp).toBeUndefined();
|
expect(deserialized.style.uselessProp).toBeUndefined();
|
||||||
expect(deserialized.uselessProp).toBeUndefined();
|
expect(deserialized.uselessProp).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("FontInfo", function () {
|
describe("FontInfo", function () {
|
||||||
it("must roundtrip correctly for FontInfo", function () {
|
it("must roundtrip correctly for FontInfo", function () {
|
||||||
let sizeEstimate = 92; // fixed offset until the strings
|
let sizeEstimate = 92; // fixed offset until the strings
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
sizeEstimate += 4 + 4 * (4 + encoder.encode("string").length);
|
sizeEstimate += 4 + 4 * (4 + encoder.encode("string").length);
|
||||||
sizeEstimate += 4 + 4; // cssFontInfo and systemFontInfo
|
sizeEstimate += 4 + 4; // cssFontInfo and systemFontInfo
|
||||||
sizeEstimate += 4 + fontInfo.data.length;
|
sizeEstimate += 4 + fontInfo.data.length;
|
||||||
const buffer = FontInfo.write(fontInfo);
|
const buffer = FontInfo.write(fontInfo);
|
||||||
expect(buffer.byteLength).toEqual(sizeEstimate);
|
expect(buffer.byteLength).toEqual(sizeEstimate);
|
||||||
const deserialized = new FontInfo({ data: buffer });
|
const deserialized = new FontInfo({ data: buffer });
|
||||||
expect(deserialized.black).toEqual(true);
|
expect(deserialized.black).toEqual(true);
|
||||||
expect(deserialized.bold).toEqual(true);
|
expect(deserialized.bold).toEqual(true);
|
||||||
expect(deserialized.disableFontFace).toEqual(true);
|
expect(deserialized.disableFontFace).toEqual(true);
|
||||||
expect(deserialized.fontExtraProperties).toEqual(true);
|
expect(deserialized.fontExtraProperties).toEqual(true);
|
||||||
expect(deserialized.isInvalidPDFjsFont).toEqual(true);
|
expect(deserialized.isInvalidPDFjsFont).toEqual(true);
|
||||||
expect(deserialized.isType3Font).toEqual(true);
|
expect(deserialized.isType3Font).toEqual(true);
|
||||||
expect(deserialized.italic).toEqual(true);
|
expect(deserialized.italic).toEqual(true);
|
||||||
expect(deserialized.missingFile).toEqual(true);
|
expect(deserialized.missingFile).toEqual(true);
|
||||||
expect(deserialized.remeasure).toEqual(true);
|
expect(deserialized.remeasure).toEqual(true);
|
||||||
expect(deserialized.vertical).toEqual(true);
|
expect(deserialized.vertical).toEqual(true);
|
||||||
expect(deserialized.ascent).toEqual(1);
|
expect(deserialized.ascent).toEqual(1);
|
||||||
expect(deserialized.defaultWidth).toEqual(1);
|
expect(deserialized.defaultWidth).toEqual(1);
|
||||||
expect(deserialized.descent).toEqual(1);
|
expect(deserialized.descent).toEqual(1);
|
||||||
expect(deserialized.bbox).toEqual([1, 1, 1, 1]);
|
expect(deserialized.bbox).toEqual([1, 1, 1, 1]);
|
||||||
expect(deserialized.fontMatrix).toEqual([1, 1, 1, 1, 1, 1]);
|
expect(deserialized.fontMatrix).toEqual([1, 1, 1, 1, 1, 1]);
|
||||||
expect(deserialized.defaultVMetrics).toEqual([1, 1, 1]);
|
expect(deserialized.defaultVMetrics).toEqual([1, 1, 1]);
|
||||||
expect(deserialized.fallbackName).toEqual("string");
|
expect(deserialized.fallbackName).toEqual("string");
|
||||||
expect(deserialized.loadedName).toEqual("string");
|
expect(deserialized.loadedName).toEqual("string");
|
||||||
expect(deserialized.mimetype).toEqual("string");
|
expect(deserialized.mimetype).toEqual("string");
|
||||||
expect(deserialized.name).toEqual("string");
|
expect(deserialized.name).toEqual("string");
|
||||||
expect(Array.from(deserialized.data)).toEqual([
|
expect(Array.from(deserialized.data)).toEqual([
|
||||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||||
]);
|
]);
|
||||||
expect(deserialized.uselessProp).toBeUndefined();
|
expect(deserialized.uselessProp).toBeUndefined();
|
||||||
expect(deserialized.cssFontInfo).toBeNull();
|
expect(deserialized.cssFontInfo).toBeNull();
|
||||||
expect(deserialized.systemFontInfo).toBeNull();
|
expect(deserialized.systemFontInfo).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("nesting should work as expected", function () {
|
it("nesting should work as expected", function () {
|
||||||
const buffer = FontInfo.write({
|
const buffer = FontInfo.write({
|
||||||
...fontInfo,
|
...fontInfo,
|
||||||
cssFontInfo,
|
cssFontInfo,
|
||||||
systemFontInfo,
|
systemFontInfo,
|
||||||
|
});
|
||||||
|
const deserialized = new FontInfo({ data: buffer });
|
||||||
|
expect(deserialized.cssFontInfo.fontWeight).toEqual("not a number");
|
||||||
|
expect(deserialized.systemFontInfo.src).toEqual("source");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
const deserialized = new FontInfo({ data: buffer });
|
|
||||||
expect(deserialized.cssFontInfo.fontWeight).toEqual("not a number");
|
|
||||||
expect(deserialized.systemFontInfo.src).toEqual("source");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const axialPatternIR = [
|
describe("Pattern data", function () {
|
||||||
"RadialAxial",
|
const axialPatternIR = [
|
||||||
"axial",
|
"RadialAxial",
|
||||||
[0, 0, 100, 50],
|
"axial",
|
||||||
[
|
[0, 0, 100, 50],
|
||||||
[0, "#ff0000"],
|
[
|
||||||
[0.5, "#00ff00"],
|
[0, "#ff0000"],
|
||||||
[1, "#0000ff"],
|
[0.5, "#00ff00"],
|
||||||
],
|
[1, "#0000ff"],
|
||||||
[10, 20],
|
],
|
||||||
[90, 40],
|
[10, 20],
|
||||||
null,
|
[90, 40],
|
||||||
null,
|
null,
|
||||||
];
|
|
||||||
|
|
||||||
const radialPatternIR = [
|
|
||||||
"RadialAxial",
|
|
||||||
"radial",
|
|
||||||
[5, 5, 95, 45],
|
|
||||||
[
|
|
||||||
[0, "#ffff00"],
|
|
||||||
[0.3, "#ff00ff"],
|
|
||||||
[0.7, "#00ffff"],
|
|
||||||
[1, "#ffffff"],
|
|
||||||
],
|
|
||||||
[25, 25],
|
|
||||||
[75, 35],
|
|
||||||
5,
|
|
||||||
25,
|
|
||||||
];
|
|
||||||
|
|
||||||
const meshPatternIR = [
|
|
||||||
"Mesh",
|
|
||||||
4,
|
|
||||||
new Float32Array([
|
|
||||||
0, 0, 50, 0, 100, 0, 0, 50, 50, 50, 100, 50, 0, 100, 50, 100, 100, 100,
|
|
||||||
]),
|
|
||||||
new Uint8Array([
|
|
||||||
255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0, 128, 128, 128, 255, 0, 255, 0,
|
|
||||||
255, 255, 255, 128, 0, 128, 0, 128,
|
|
||||||
]),
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: MeshFigureType.TRIANGLES,
|
|
||||||
coords: new Int32Array([0, 2, 4, 6, 8, 10, 12, 14, 16]),
|
|
||||||
colors: new Int32Array([0, 2, 4, 6, 8, 10, 12, 14, 16]),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: MeshFigureType.LATTICE,
|
|
||||||
coords: new Int32Array([0, 2, 4, 6, 8, 10]),
|
|
||||||
colors: new Int32Array([0, 2, 4, 6, 8, 10]),
|
|
||||||
verticesPerRow: 3,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[0, 0, 100, 100],
|
|
||||||
[0, 0, 100, 100],
|
|
||||||
[128, 128, 128],
|
|
||||||
];
|
|
||||||
|
|
||||||
describe("Pattern serialization and deserialization", function () {
|
|
||||||
it("must serialize and deserialize axial gradients correctly", function () {
|
|
||||||
const buffer = PatternInfo.write(axialPatternIR);
|
|
||||||
expect(buffer).toBeInstanceOf(ArrayBuffer);
|
|
||||||
expect(buffer.byteLength).toBeGreaterThan(0);
|
|
||||||
|
|
||||||
const patternInfo = new PatternInfo(buffer);
|
|
||||||
const reconstructedIR = patternInfo.getIR();
|
|
||||||
|
|
||||||
expect(reconstructedIR[0]).toEqual("RadialAxial");
|
|
||||||
expect(reconstructedIR[1]).toEqual("axial");
|
|
||||||
expect(reconstructedIR[2]).toEqual([0, 0, 100, 50]);
|
|
||||||
expect(reconstructedIR[3]).toEqual([
|
|
||||||
[0, "#ff0000"],
|
|
||||||
[0.5, "#00ff00"],
|
|
||||||
[1, "#0000ff"],
|
|
||||||
]);
|
|
||||||
expect(reconstructedIR[4]).toEqual([10, 20]);
|
|
||||||
expect(reconstructedIR[5]).toEqual([90, 40]);
|
|
||||||
expect(reconstructedIR[6]).toBeNull();
|
|
||||||
expect(reconstructedIR[7]).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("must serialize and deserialize radial gradients correctly", function () {
|
|
||||||
const buffer = PatternInfo.write(radialPatternIR);
|
|
||||||
expect(buffer).toBeInstanceOf(ArrayBuffer);
|
|
||||||
expect(buffer.byteLength).toBeGreaterThan(0);
|
|
||||||
|
|
||||||
const patternInfo = new PatternInfo(buffer);
|
|
||||||
const reconstructedIR = patternInfo.getIR();
|
|
||||||
|
|
||||||
expect(reconstructedIR[0]).toEqual("RadialAxial");
|
|
||||||
expect(reconstructedIR[1]).toEqual("radial");
|
|
||||||
expect(reconstructedIR[2]).toEqual([5, 5, 95, 45]);
|
|
||||||
expect(reconstructedIR[3]).toEqual([
|
|
||||||
[0, "#ffff00"],
|
|
||||||
jasmine.objectContaining([jasmine.any(Number), "#ff00ff"]),
|
|
||||||
jasmine.objectContaining([jasmine.any(Number), "#00ffff"]),
|
|
||||||
[1, "#ffffff"],
|
|
||||||
]);
|
|
||||||
expect(reconstructedIR[4]).toEqual([25, 25]);
|
|
||||||
expect(reconstructedIR[5]).toEqual([75, 35]);
|
|
||||||
expect(reconstructedIR[6]).toEqual(5);
|
|
||||||
expect(reconstructedIR[7]).toEqual(25);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("must serialize and deserialize mesh patterns with figures correctly", function () {
|
|
||||||
const buffer = PatternInfo.write(meshPatternIR);
|
|
||||||
expect(buffer).toBeInstanceOf(ArrayBuffer);
|
|
||||||
expect(buffer.byteLength).toBeGreaterThan(0);
|
|
||||||
|
|
||||||
const patternInfo = new PatternInfo(buffer);
|
|
||||||
const reconstructedIR = patternInfo.getIR();
|
|
||||||
|
|
||||||
expect(reconstructedIR[0]).toEqual("Mesh");
|
|
||||||
expect(reconstructedIR[1]).toEqual(4);
|
|
||||||
|
|
||||||
expect(reconstructedIR[2]).toBeInstanceOf(Float32Array);
|
|
||||||
expect(Array.from(reconstructedIR[2])).toEqual(
|
|
||||||
Array.from(meshPatternIR[2])
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(reconstructedIR[3]).toBeInstanceOf(Uint8Array);
|
|
||||||
expect(Array.from(reconstructedIR[3])).toEqual(
|
|
||||||
Array.from(meshPatternIR[3])
|
|
||||||
);
|
|
||||||
expect(reconstructedIR[4].length).toEqual(2);
|
|
||||||
|
|
||||||
const fig1 = reconstructedIR[4][0];
|
|
||||||
expect(fig1.type).toEqual(MeshFigureType.TRIANGLES);
|
|
||||||
expect(fig1.coords).toBeInstanceOf(Int32Array);
|
|
||||||
expect(Array.from(fig1.coords)).toEqual([0, 2, 4, 6, 8, 10, 12, 14, 16]);
|
|
||||||
expect(fig1.colors).toBeInstanceOf(Int32Array);
|
|
||||||
expect(Array.from(fig1.colors)).toEqual([0, 2, 4, 6, 8, 10, 12, 14, 16]);
|
|
||||||
expect(fig1.verticesPerRow).toBeUndefined();
|
|
||||||
|
|
||||||
const fig2 = reconstructedIR[4][1];
|
|
||||||
expect(fig2.type).toEqual(MeshFigureType.LATTICE);
|
|
||||||
expect(fig2.coords).toBeInstanceOf(Int32Array);
|
|
||||||
expect(Array.from(fig2.coords)).toEqual([0, 2, 4, 6, 8, 10]);
|
|
||||||
expect(fig2.colors).toBeInstanceOf(Int32Array);
|
|
||||||
expect(Array.from(fig2.colors)).toEqual([0, 2, 4, 6, 8, 10]);
|
|
||||||
expect(fig2.verticesPerRow).toEqual(3);
|
|
||||||
|
|
||||||
expect(reconstructedIR[5]).toEqual([0, 0, 100, 100]);
|
|
||||||
expect(reconstructedIR[6]).toEqual([0, 0, 100, 100]);
|
|
||||||
expect(reconstructedIR[7]).toBeInstanceOf(Uint8Array);
|
|
||||||
expect(Array.from(reconstructedIR[7])).toEqual([128, 128, 128]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("must handle mesh patterns with no figures", function () {
|
|
||||||
const noFiguresIR = [
|
|
||||||
"Mesh",
|
|
||||||
4,
|
|
||||||
new Float32Array([0, 0, 10, 10]),
|
|
||||||
new Uint8Array([255, 0, 0]),
|
|
||||||
[],
|
|
||||||
[0, 0, 10, 10],
|
|
||||||
[0, 0, 10, 10],
|
|
||||||
null,
|
null,
|
||||||
];
|
];
|
||||||
|
|
||||||
const buffer = PatternInfo.write(noFiguresIR);
|
const radialPatternIR = [
|
||||||
const patternInfo = new PatternInfo(buffer);
|
"RadialAxial",
|
||||||
const reconstructedIR = patternInfo.getIR();
|
"radial",
|
||||||
|
[5, 5, 95, 45],
|
||||||
|
[
|
||||||
|
[0, "#ffff00"],
|
||||||
|
[0.3, "#ff00ff"],
|
||||||
|
[0.7, "#00ffff"],
|
||||||
|
[1, "#ffffff"],
|
||||||
|
],
|
||||||
|
[25, 25],
|
||||||
|
[75, 35],
|
||||||
|
5,
|
||||||
|
25,
|
||||||
|
];
|
||||||
|
|
||||||
expect(reconstructedIR[4]).toEqual([]);
|
const meshPatternIR = [
|
||||||
expect(reconstructedIR[7]).toBeNull(); // background should be null
|
|
||||||
});
|
|
||||||
|
|
||||||
it("must preserve figure data integrity across serialization", function () {
|
|
||||||
const buffer = PatternInfo.write(meshPatternIR);
|
|
||||||
const patternInfo = new PatternInfo(buffer);
|
|
||||||
const reconstructedIR = patternInfo.getIR();
|
|
||||||
|
|
||||||
// Verify data integrity by checking exact values
|
|
||||||
const originalFig = meshPatternIR[4][0];
|
|
||||||
const reconstructedFig = reconstructedIR[4][0];
|
|
||||||
|
|
||||||
for (let i = 0; i < originalFig.coords.length; i++) {
|
|
||||||
expect(reconstructedFig.coords[i]).toEqual(originalFig.coords[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < originalFig.colors.length; i++) {
|
|
||||||
expect(reconstructedFig.colors[i]).toEqual(originalFig.colors[i]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it("must calculate correct buffer sizes for different pattern types", function () {
|
|
||||||
const axialBuffer = PatternInfo.write(axialPatternIR);
|
|
||||||
const radialBuffer = PatternInfo.write(radialPatternIR);
|
|
||||||
const meshBuffer = PatternInfo.write(meshPatternIR);
|
|
||||||
|
|
||||||
expect(axialBuffer.byteLength).toBeLessThan(radialBuffer.byteLength);
|
|
||||||
expect(meshBuffer.byteLength).toBeGreaterThan(axialBuffer.byteLength);
|
|
||||||
expect(meshBuffer.byteLength).toBeGreaterThan(radialBuffer.byteLength);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("must handle figures with different type enums correctly", function () {
|
|
||||||
const customFiguresIR = [
|
|
||||||
"Mesh",
|
"Mesh",
|
||||||
6,
|
4,
|
||||||
new Float32Array([0, 0, 10, 10]),
|
new Float32Array([
|
||||||
new Uint8Array([255, 128, 64]),
|
0, 0, 50, 0, 100, 0, 0, 50, 50, 50, 100, 50, 0, 100, 50, 100, 100, 100,
|
||||||
|
]),
|
||||||
|
new Uint8Array([
|
||||||
|
255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0, 128, 128, 128, 255, 0,
|
||||||
|
255, 0, 255, 255, 255, 128, 0, 128, 0, 128,
|
||||||
|
]),
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
type: MeshFigureType.PATCH,
|
type: MeshFigureType.TRIANGLES,
|
||||||
coords: new Int32Array([0, 2]),
|
coords: new Int32Array([0, 2, 4, 6, 8, 10, 12, 14, 16]),
|
||||||
colors: new Int32Array([0, 2]),
|
colors: new Int32Array([0, 2, 4, 6, 8, 10, 12, 14, 16]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: MeshFigureType.TRIANGLES,
|
type: MeshFigureType.LATTICE,
|
||||||
coords: new Int32Array([0]),
|
coords: new Int32Array([0, 2, 4, 6, 8, 10]),
|
||||||
colors: new Int32Array([0]),
|
colors: new Int32Array([0, 2, 4, 6, 8, 10]),
|
||||||
|
verticesPerRow: 3,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[0, 0, 10, 10],
|
[0, 0, 100, 100],
|
||||||
null,
|
[0, 0, 100, 100],
|
||||||
null,
|
[128, 128, 128],
|
||||||
];
|
];
|
||||||
|
|
||||||
const buffer = PatternInfo.write(customFiguresIR);
|
describe("Pattern serialization and deserialization", function () {
|
||||||
const patternInfo = new PatternInfo(buffer);
|
it("must serialize and deserialize axial gradients correctly", function () {
|
||||||
const reconstructedIR = patternInfo.getIR();
|
const buffer = PatternInfo.write(axialPatternIR);
|
||||||
|
expect(buffer).toBeInstanceOf(ArrayBuffer);
|
||||||
|
expect(buffer.byteLength).toBeGreaterThan(0);
|
||||||
|
|
||||||
expect(reconstructedIR[4].length).toEqual(2);
|
const patternInfo = new PatternInfo(buffer);
|
||||||
expect(reconstructedIR[4][0].type).toEqual(MeshFigureType.PATCH);
|
const reconstructedIR = patternInfo.getIR();
|
||||||
expect(reconstructedIR[4][1].type).toEqual(MeshFigureType.TRIANGLES);
|
|
||||||
|
expect(reconstructedIR[0]).toEqual("RadialAxial");
|
||||||
|
expect(reconstructedIR[1]).toEqual("axial");
|
||||||
|
expect(reconstructedIR[2]).toEqual([0, 0, 100, 50]);
|
||||||
|
expect(reconstructedIR[3]).toEqual([
|
||||||
|
[0, "#ff0000"],
|
||||||
|
[0.5, "#00ff00"],
|
||||||
|
[1, "#0000ff"],
|
||||||
|
]);
|
||||||
|
expect(reconstructedIR[4]).toEqual([10, 20]);
|
||||||
|
expect(reconstructedIR[5]).toEqual([90, 40]);
|
||||||
|
expect(reconstructedIR[6]).toBeNull();
|
||||||
|
expect(reconstructedIR[7]).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must serialize and deserialize radial gradients correctly", function () {
|
||||||
|
const buffer = PatternInfo.write(radialPatternIR);
|
||||||
|
expect(buffer).toBeInstanceOf(ArrayBuffer);
|
||||||
|
expect(buffer.byteLength).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
const patternInfo = new PatternInfo(buffer);
|
||||||
|
const reconstructedIR = patternInfo.getIR();
|
||||||
|
|
||||||
|
expect(reconstructedIR[0]).toEqual("RadialAxial");
|
||||||
|
expect(reconstructedIR[1]).toEqual("radial");
|
||||||
|
expect(reconstructedIR[2]).toEqual([5, 5, 95, 45]);
|
||||||
|
expect(reconstructedIR[3]).toEqual([
|
||||||
|
[0, "#ffff00"],
|
||||||
|
jasmine.objectContaining([jasmine.any(Number), "#ff00ff"]),
|
||||||
|
jasmine.objectContaining([jasmine.any(Number), "#00ffff"]),
|
||||||
|
[1, "#ffffff"],
|
||||||
|
]);
|
||||||
|
expect(reconstructedIR[4]).toEqual([25, 25]);
|
||||||
|
expect(reconstructedIR[5]).toEqual([75, 35]);
|
||||||
|
expect(reconstructedIR[6]).toEqual(5);
|
||||||
|
expect(reconstructedIR[7]).toEqual(25);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must serialize and deserialize mesh patterns with figures correctly", function () {
|
||||||
|
const buffer = PatternInfo.write(meshPatternIR);
|
||||||
|
expect(buffer).toBeInstanceOf(ArrayBuffer);
|
||||||
|
expect(buffer.byteLength).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
const patternInfo = new PatternInfo(buffer);
|
||||||
|
const reconstructedIR = patternInfo.getIR();
|
||||||
|
|
||||||
|
expect(reconstructedIR[0]).toEqual("Mesh");
|
||||||
|
expect(reconstructedIR[1]).toEqual(4);
|
||||||
|
|
||||||
|
expect(reconstructedIR[2]).toBeInstanceOf(Float32Array);
|
||||||
|
expect(Array.from(reconstructedIR[2])).toEqual(
|
||||||
|
Array.from(meshPatternIR[2])
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(reconstructedIR[3]).toBeInstanceOf(Uint8Array);
|
||||||
|
expect(Array.from(reconstructedIR[3])).toEqual(
|
||||||
|
Array.from(meshPatternIR[3])
|
||||||
|
);
|
||||||
|
expect(reconstructedIR[4].length).toEqual(2);
|
||||||
|
|
||||||
|
const fig1 = reconstructedIR[4][0];
|
||||||
|
expect(fig1.type).toEqual(MeshFigureType.TRIANGLES);
|
||||||
|
expect(fig1.coords).toBeInstanceOf(Int32Array);
|
||||||
|
expect(Array.from(fig1.coords)).toEqual([
|
||||||
|
0, 2, 4, 6, 8, 10, 12, 14, 16,
|
||||||
|
]);
|
||||||
|
expect(fig1.colors).toBeInstanceOf(Int32Array);
|
||||||
|
expect(Array.from(fig1.colors)).toEqual([
|
||||||
|
0, 2, 4, 6, 8, 10, 12, 14, 16,
|
||||||
|
]);
|
||||||
|
expect(fig1.verticesPerRow).toBeUndefined();
|
||||||
|
|
||||||
|
const fig2 = reconstructedIR[4][1];
|
||||||
|
expect(fig2.type).toEqual(MeshFigureType.LATTICE);
|
||||||
|
expect(fig2.coords).toBeInstanceOf(Int32Array);
|
||||||
|
expect(Array.from(fig2.coords)).toEqual([0, 2, 4, 6, 8, 10]);
|
||||||
|
expect(fig2.colors).toBeInstanceOf(Int32Array);
|
||||||
|
expect(Array.from(fig2.colors)).toEqual([0, 2, 4, 6, 8, 10]);
|
||||||
|
expect(fig2.verticesPerRow).toEqual(3);
|
||||||
|
|
||||||
|
expect(reconstructedIR[5]).toEqual([0, 0, 100, 100]);
|
||||||
|
expect(reconstructedIR[6]).toEqual([0, 0, 100, 100]);
|
||||||
|
expect(reconstructedIR[7]).toBeInstanceOf(Uint8Array);
|
||||||
|
expect(Array.from(reconstructedIR[7])).toEqual([128, 128, 128]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must handle mesh patterns with no figures", function () {
|
||||||
|
const noFiguresIR = [
|
||||||
|
"Mesh",
|
||||||
|
4,
|
||||||
|
new Float32Array([0, 0, 10, 10]),
|
||||||
|
new Uint8Array([255, 0, 0]),
|
||||||
|
[],
|
||||||
|
[0, 0, 10, 10],
|
||||||
|
[0, 0, 10, 10],
|
||||||
|
null,
|
||||||
|
];
|
||||||
|
|
||||||
|
const buffer = PatternInfo.write(noFiguresIR);
|
||||||
|
const patternInfo = new PatternInfo(buffer);
|
||||||
|
const reconstructedIR = patternInfo.getIR();
|
||||||
|
|
||||||
|
expect(reconstructedIR[4]).toEqual([]);
|
||||||
|
expect(reconstructedIR[7]).toBeNull(); // background should be null
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must preserve figure data integrity across serialization", function () {
|
||||||
|
const buffer = PatternInfo.write(meshPatternIR);
|
||||||
|
const patternInfo = new PatternInfo(buffer);
|
||||||
|
const reconstructedIR = patternInfo.getIR();
|
||||||
|
|
||||||
|
// Verify data integrity by checking exact values
|
||||||
|
const originalFig = meshPatternIR[4][0];
|
||||||
|
const reconstructedFig = reconstructedIR[4][0];
|
||||||
|
|
||||||
|
for (let i = 0; i < originalFig.coords.length; i++) {
|
||||||
|
expect(reconstructedFig.coords[i]).toEqual(originalFig.coords[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < originalFig.colors.length; i++) {
|
||||||
|
expect(reconstructedFig.colors[i]).toEqual(originalFig.colors[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must calculate correct buffer sizes for different pattern types", function () {
|
||||||
|
const axialBuffer = PatternInfo.write(axialPatternIR);
|
||||||
|
const radialBuffer = PatternInfo.write(radialPatternIR);
|
||||||
|
const meshBuffer = PatternInfo.write(meshPatternIR);
|
||||||
|
|
||||||
|
expect(axialBuffer.byteLength).toBeLessThan(radialBuffer.byteLength);
|
||||||
|
expect(meshBuffer.byteLength).toBeGreaterThan(axialBuffer.byteLength);
|
||||||
|
expect(meshBuffer.byteLength).toBeGreaterThan(radialBuffer.byteLength);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must handle figures with different type enums correctly", function () {
|
||||||
|
const customFiguresIR = [
|
||||||
|
"Mesh",
|
||||||
|
6,
|
||||||
|
new Float32Array([0, 0, 10, 10]),
|
||||||
|
new Uint8Array([255, 128, 64]),
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: MeshFigureType.PATCH,
|
||||||
|
coords: new Int32Array([0, 2]),
|
||||||
|
colors: new Int32Array([0, 2]),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: MeshFigureType.TRIANGLES,
|
||||||
|
coords: new Int32Array([0]),
|
||||||
|
colors: new Int32Array([0]),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[0, 0, 10, 10],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
];
|
||||||
|
|
||||||
|
const buffer = PatternInfo.write(customFiguresIR);
|
||||||
|
const patternInfo = new PatternInfo(buffer);
|
||||||
|
const reconstructedIR = patternInfo.getIR();
|
||||||
|
|
||||||
|
expect(reconstructedIR[4].length).toEqual(2);
|
||||||
|
expect(reconstructedIR[4][0].type).toEqual(MeshFigureType.PATCH);
|
||||||
|
expect(reconstructedIR[4][1].type).toEqual(MeshFigureType.TRIANGLES);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must handle mesh patterns with different background values", function () {
|
||||||
|
const meshWithBgIR = [
|
||||||
|
"Mesh",
|
||||||
|
4,
|
||||||
|
new Float32Array([0, 0, 10, 10]),
|
||||||
|
new Uint8Array([255, 0, 0]),
|
||||||
|
[],
|
||||||
|
[0, 0, 10, 10],
|
||||||
|
[0, 0, 10, 10],
|
||||||
|
new Uint8Array([255, 128, 64]),
|
||||||
|
];
|
||||||
|
|
||||||
|
const buffer = PatternInfo.write(meshWithBgIR);
|
||||||
|
const patternInfo = new PatternInfo(buffer);
|
||||||
|
const reconstructedIR = patternInfo.getIR();
|
||||||
|
|
||||||
|
expect(reconstructedIR[7]).toBeInstanceOf(Uint8Array);
|
||||||
|
expect(Array.from(reconstructedIR[7])).toEqual([255, 128, 64]);
|
||||||
|
const meshNoBgIR = [
|
||||||
|
"Mesh",
|
||||||
|
5,
|
||||||
|
new Float32Array([0, 0, 5, 5]),
|
||||||
|
new Uint8Array([0, 255, 0]),
|
||||||
|
[],
|
||||||
|
[0, 0, 5, 5],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
];
|
||||||
|
|
||||||
|
const buffer2 = PatternInfo.write(meshNoBgIR);
|
||||||
|
const patternInfo2 = new PatternInfo(buffer2);
|
||||||
|
const reconstructedIR2 = patternInfo2.getIR();
|
||||||
|
|
||||||
|
expect(reconstructedIR2[7]).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must calculate bounds correctly from coordinates", function () {
|
||||||
|
const customMeshIR = [
|
||||||
|
"Mesh",
|
||||||
|
4,
|
||||||
|
new Float32Array([-10, -5, 20, 15, 0, 30]),
|
||||||
|
new Uint8Array([255, 0, 0, 0, 255, 0, 0, 0, 255]),
|
||||||
|
[],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
];
|
||||||
|
|
||||||
|
const buffer = PatternInfo.write(customMeshIR);
|
||||||
|
const patternInfo = new PatternInfo(buffer);
|
||||||
|
const reconstructedIR = patternInfo.getIR();
|
||||||
|
|
||||||
|
expect(reconstructedIR[5]).toEqual([-10, -5, 20, 30]);
|
||||||
|
expect(reconstructedIR[7]).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("must handle mesh patterns with different background values", function () {
|
describe("FontPath data", function () {
|
||||||
const meshWithBgIR = [
|
const path = FeatureTest.isFloat16ArraySupported
|
||||||
"Mesh",
|
? new Float16Array([
|
||||||
4,
|
0.214, 0.27, 0.23, 0.33, 0.248, 0.395, 0.265, 0.471, 0.281, 0.54,
|
||||||
new Float32Array([0, 0, 10, 10]),
|
0.285, 0.54, 0.302, 0.472, 0.32, 0.395, 0.338, 0.33, 0.353, 0.27,
|
||||||
new Uint8Array([255, 0, 0]),
|
0.214, 0.27, 0.423, 0, 0.579, 0, 0.375, 0.652, 0.198, 0.652, -0.006,
|
||||||
[],
|
0, 0.144, 0, 0.184, 0.155, 0.383, 0.155,
|
||||||
[0, 0, 10, 10],
|
])
|
||||||
[0, 0, 10, 10],
|
: new Float32Array([
|
||||||
new Uint8Array([255, 128, 64]),
|
0.214, 0.27, 0.23, 0.33, 0.248, 0.395, 0.265, 0.471, 0.281, 0.54,
|
||||||
];
|
0.285, 0.54, 0.302, 0.472, 0.32, 0.395, 0.338, 0.33, 0.353, 0.27,
|
||||||
|
0.214, 0.27, 0.423, 0, 0.579, 0, 0.375, 0.652, 0.198, 0.652, -0.006,
|
||||||
|
0, 0.144, 0, 0.184, 0.155, 0.383, 0.155,
|
||||||
|
]);
|
||||||
|
|
||||||
const buffer = PatternInfo.write(meshWithBgIR);
|
it("should create a FontPathInfo instance from an array of path commands", function () {
|
||||||
const patternInfo = new PatternInfo(buffer);
|
const buffer = FontPathInfo.write(path);
|
||||||
const reconstructedIR = patternInfo.getIR();
|
const fontPathInfo = new FontPathInfo(buffer);
|
||||||
|
expect(fontPathInfo.path).toEqual(path);
|
||||||
expect(reconstructedIR[7]).toBeInstanceOf(Uint8Array);
|
});
|
||||||
expect(Array.from(reconstructedIR[7])).toEqual([255, 128, 64]);
|
|
||||||
const meshNoBgIR = [
|
|
||||||
"Mesh",
|
|
||||||
5,
|
|
||||||
new Float32Array([0, 0, 5, 5]),
|
|
||||||
new Uint8Array([0, 255, 0]),
|
|
||||||
[],
|
|
||||||
[0, 0, 5, 5],
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
];
|
|
||||||
|
|
||||||
const buffer2 = PatternInfo.write(meshNoBgIR);
|
|
||||||
const patternInfo2 = new PatternInfo(buffer2);
|
|
||||||
const reconstructedIR2 = patternInfo2.getIR();
|
|
||||||
|
|
||||||
expect(reconstructedIR2[7]).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("must calculate bounds correctly from coordinates", function () {
|
|
||||||
const customMeshIR = [
|
|
||||||
"Mesh",
|
|
||||||
4,
|
|
||||||
new Float32Array([-10, -5, 20, 15, 0, 30]),
|
|
||||||
new Uint8Array([255, 0, 0, 0, 255, 0, 0, 0, 255]),
|
|
||||||
[],
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
];
|
|
||||||
|
|
||||||
const buffer = PatternInfo.write(customMeshIR);
|
|
||||||
const patternInfo = new PatternInfo(buffer);
|
|
||||||
const reconstructedIR = patternInfo.getIR();
|
|
||||||
|
|
||||||
expect(reconstructedIR[5]).toEqual([-10, -5, 20, 30]);
|
|
||||||
expect(reconstructedIR[7]).toBeNull();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user