1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-26 01:58:06 +02:00

Add the possibility to rescale each glyph in a font

- a lot of xfa files are using Myriad pro or Arial fonts without embedding them and some containers have some dimensions based on those font metrics. So not having the exact same font leads to a wrong display.
  - since it's pretty hard to find a replacement font with the exact same metrics, this patch gives the possibility to read glyf table, rescale each glyph and then write a new table.
  - so once PR #12726 is merged we could rescale for example Helvetica to replace Myriad Pro.
This commit is contained in:
Calixte Denizet 2021-05-10 11:54:38 +02:00
parent ae531e5e23
commit fd1110adb4
2 changed files with 754 additions and 0 deletions

View file

@ -57,6 +57,7 @@ import {
import { IdentityToUnicodeMap, ToUnicodeMap } from "./to_unicode_map.js";
import { CFFFont } from "./cff_font.js";
import { FontRendererFactory } from "./font_renderer.js";
import { GlyfTable } from "./glyf.js";
import { IdentityCMap } from "./cmap.js";
import { OpenTypeFileBuilder } from "./opentype_file_builder.js";
import { readUint32 } from "./core_utils.js";
@ -2323,6 +2324,51 @@ class Font {
font.pos = (font.start || 0) + tables.maxp.offset;
const version = font.getInt32();
const numGlyphs = font.getUint16();
if (
properties.scaleFactors &&
properties.scaleFactors.length === numGlyphs &&
isTrueType
) {
const { scaleFactors } = properties;
const isGlyphLocationsLong = int16(
tables.head.data[50],
tables.head.data[51]
);
const glyphs = new GlyfTable({
glyfTable: tables.glyf.data,
isGlyphLocationsLong,
locaTable: tables.loca.data,
numGlyphs,
});
glyphs.scale(scaleFactors);
const { glyf, loca, isLocationLong } = glyphs.write();
tables.glyf.data = glyf;
tables.loca.data = loca;
if (isLocationLong !== !!isGlyphLocationsLong) {
tables.head.data[50] = 0;
tables.head.data[51] = isLocationLong ? 1 : 0;
}
const metrics = tables.hmtx.data;
for (let i = 0; i < numGlyphs; i++) {
const j = 4 * i;
const advanceWidth = Math.round(
scaleFactors[i] * int16(metrics[j], metrics[j + 1])
);
metrics[j] = (advanceWidth >> 8) & 0xff;
metrics[j + 1] = advanceWidth & 0xff;
const lsb = Math.round(
scaleFactors[i] * signedInt16(metrics[j + 2], metrics[j + 3])
);
writeSignedInt16(metrics, j + 2, lsb);
}
}
// Glyph 0 is duplicated and appended.
let numGlyphsOut = numGlyphs + 1;
let dupFirstEntry = true;