Merge 4fed542e3f808350cc4fdb37013b368b12778071 into a96553648551b94652f4b1139c440d53c806836f

This commit is contained in:
Ujjwal Sharma 2025-11-29 04:20:42 +05:30 committed by GitHub
commit 94e48bc23b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 490 additions and 414 deletions

View File

@ -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}".`);

View File

@ -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;

View File

@ -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.

View File

@ -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 };

View File

@ -16,19 +16,22 @@
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 () {
describe("Font data", function () {
const cssFontInfo = {
fontFamily: "Sample Family", fontFamily: "Sample Family",
fontWeight: "not a number", fontWeight: "not a number",
italicAngle: "angle", italicAngle: "angle",
uselessProp: "doesn't matter", uselessProp: "doesn't matter",
}; };
const systemFontInfo = { const systemFontInfo = {
guessFallback: false, guessFallback: false,
css: "some string", css: "some string",
loadedName: "another string", loadedName: "another string",
@ -40,9 +43,9 @@ const systemFontInfo = {
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,
@ -65,9 +68,9 @@ const fontInfo = {
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();
@ -163,9 +166,11 @@ describe("font data serialization and deserialization", function () {
expect(deserialized.systemFontInfo.src).toEqual("source"); expect(deserialized.systemFontInfo.src).toEqual("source");
}); });
}); });
}); });
});
const axialPatternIR = [ describe("Pattern data", function () {
const axialPatternIR = [
"RadialAxial", "RadialAxial",
"axial", "axial",
[0, 0, 100, 50], [0, 0, 100, 50],
@ -178,9 +183,9 @@ const axialPatternIR = [
[90, 40], [90, 40],
null, null,
null, null,
]; ];
const radialPatternIR = [ const radialPatternIR = [
"RadialAxial", "RadialAxial",
"radial", "radial",
[5, 5, 95, 45], [5, 5, 95, 45],
@ -194,17 +199,17 @@ const radialPatternIR = [
[75, 35], [75, 35],
5, 5,
25, 25,
]; ];
const meshPatternIR = [ const meshPatternIR = [
"Mesh", "Mesh",
4, 4,
new Float32Array([ new Float32Array([
0, 0, 50, 0, 100, 0, 0, 50, 50, 50, 100, 50, 0, 100, 50, 100, 100, 100, 0, 0, 50, 0, 100, 0, 0, 50, 50, 50, 100, 50, 0, 100, 50, 100, 100, 100,
]), ]),
new Uint8Array([ new Uint8Array([
255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0, 128, 128, 128, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0, 128, 128, 128, 255, 0,
255, 255, 255, 128, 0, 128, 0, 128, 255, 0, 255, 255, 255, 128, 0, 128, 0, 128,
]), ]),
[ [
{ {
@ -222,9 +227,9 @@ const meshPatternIR = [
[0, 0, 100, 100], [0, 0, 100, 100],
[0, 0, 100, 100], [0, 0, 100, 100],
[128, 128, 128], [128, 128, 128],
]; ];
describe("Pattern serialization and deserialization", function () { describe("Pattern serialization and deserialization", function () {
it("must serialize and deserialize axial gradients correctly", function () { it("must serialize and deserialize axial gradients correctly", function () {
const buffer = PatternInfo.write(axialPatternIR); const buffer = PatternInfo.write(axialPatternIR);
expect(buffer).toBeInstanceOf(ArrayBuffer); expect(buffer).toBeInstanceOf(ArrayBuffer);
@ -295,9 +300,13 @@ describe("Pattern serialization and deserialization", function () {
const fig1 = reconstructedIR[4][0]; const fig1 = reconstructedIR[4][0];
expect(fig1.type).toEqual(MeshFigureType.TRIANGLES); expect(fig1.type).toEqual(MeshFigureType.TRIANGLES);
expect(fig1.coords).toBeInstanceOf(Int32Array); expect(fig1.coords).toBeInstanceOf(Int32Array);
expect(Array.from(fig1.coords)).toEqual([0, 2, 4, 6, 8, 10, 12, 14, 16]); expect(Array.from(fig1.coords)).toEqual([
0, 2, 4, 6, 8, 10, 12, 14, 16,
]);
expect(fig1.colors).toBeInstanceOf(Int32Array); expect(fig1.colors).toBeInstanceOf(Int32Array);
expect(Array.from(fig1.colors)).toEqual([0, 2, 4, 6, 8, 10, 12, 14, 16]); expect(Array.from(fig1.colors)).toEqual([
0, 2, 4, 6, 8, 10, 12, 14, 16,
]);
expect(fig1.verticesPerRow).toBeUndefined(); expect(fig1.verticesPerRow).toBeUndefined();
const fig2 = reconstructedIR[4][1]; const fig2 = reconstructedIR[4][1];
@ -449,4 +458,28 @@ describe("Pattern serialization and deserialization", function () {
expect(reconstructedIR[5]).toEqual([-10, -5, 20, 30]); expect(reconstructedIR[5]).toEqual([-10, -5, 20, 30]);
expect(reconstructedIR[7]).toBeNull(); expect(reconstructedIR[7]).toBeNull();
}); });
});
});
describe("FontPath data", function () {
const path = FeatureTest.isFloat16ArraySupported
? new Float16Array([
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,
])
: new Float32Array([
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,
]);
it("should create a FontPathInfo instance from an array of path commands", function () {
const buffer = FontPathInfo.write(path);
const fontPathInfo = new FontPathInfo(buffer);
expect(fontPathInfo.path).toEqual(path);
});
});
}); });