mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-10-04 06:18:00 +02:00
Compare commits
23
Commits
c33c32aed4
...
ef62f31f24
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef62f31f24 | ||
|
|
c7e2fe4d29 | ||
|
|
8496056b9a | ||
|
|
db561fecc6 | ||
|
|
a00ad131fd | ||
|
|
20b2e11213 | ||
|
|
0f116c95da | ||
|
|
f576c25bcd | ||
|
|
fecddae585 | ||
|
|
637ed4cfe3 | ||
|
|
5baa62329e | ||
|
|
fe0e9afdb1 | ||
|
|
90448db27e | ||
|
|
dc7ac33fcd | ||
|
|
b6753b1bf3 | ||
|
|
1d43a5a956 | ||
|
|
c58ed927af | ||
|
|
05566bd110 | ||
|
|
cf2db3a426 | ||
|
|
f1c5c1513d | ||
|
|
9a6b3808ba | ||
|
|
08526f78df | ||
|
|
f1907720a8 |
@@ -55,7 +55,7 @@ jobs:
|
|||||||
enableCrossOsArchive: true
|
enableCrossOsArchive: true
|
||||||
|
|
||||||
- name: Upload results to Codecov
|
- name: Upload results to Codecov
|
||||||
uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7.1.0
|
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
|
uses: github/codeql-action/init@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
queries: security-and-quality
|
queries: security-and-quality
|
||||||
|
|
||||||
- name: Autobuild CodeQL
|
- name: Autobuild CodeQL
|
||||||
uses: github/codeql-action/autobuild@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
|
uses: github/codeql-action/autobuild@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
|
||||||
|
|
||||||
- name: Perform CodeQL analysis
|
- name: Perform CodeQL analysis
|
||||||
uses: github/codeql-action/analyze@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
|
uses: github/codeql-action/analyze@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ jobs:
|
|||||||
enableCrossOsArchive: true
|
enableCrossOsArchive: true
|
||||||
|
|
||||||
- name: Upload results to Codecov
|
- name: Upload results to Codecov
|
||||||
uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7.1.0
|
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
run: npx gulp fonttest --headless --coverage --coverage-output build/coverage/font ${{ matrix.skip }}
|
run: npx gulp fonttest --headless --coverage --coverage-output build/coverage/font ${{ matrix.skip }}
|
||||||
|
|
||||||
- name: Upload results to Codecov
|
- name: Upload results to Codecov
|
||||||
uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7.1.0
|
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ jobs:
|
|||||||
enableCrossOsArchive: true
|
enableCrossOsArchive: true
|
||||||
|
|
||||||
- name: Upload results to Codecov
|
- name: Upload results to Codecov
|
||||||
uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7.1.0
|
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ jobs:
|
|||||||
enableCrossOsArchive: true
|
enableCrossOsArchive: true
|
||||||
|
|
||||||
- name: Upload results to Codecov
|
- name: Upload results to Codecov
|
||||||
uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7.1.0
|
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|||||||
Generated
+14
-14
@@ -5325,9 +5325,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "5.0.9",
|
"version": "5.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
|
||||||
"integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
|
"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -9141,9 +9141,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/markdown-it": {
|
"node_modules/markdown-it": {
|
||||||
"version": "14.2.0",
|
"version": "14.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.2.tgz",
|
||||||
"integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==",
|
"integrity": "sha512-sHHjZ5fJKlgrG4qns2YwVcdNep35h5fERrfkD2YNsb9UFk0UIHarbiTaHKVMlPuWAoiilyK8Fv/jAm11slsY7Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -9158,8 +9158,8 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"argparse": "^2.0.1",
|
"argparse": "^2.0.1",
|
||||||
"entities": "^4.4.0",
|
"entities": "^4.5.0",
|
||||||
"linkify-it": "^5.0.1",
|
"linkify-it": "^5.0.2",
|
||||||
"mdurl": "^2.0.0",
|
"mdurl": "^2.0.0",
|
||||||
"punycode.js": "^2.3.1",
|
"punycode.js": "^2.3.1",
|
||||||
"uc.micro": "^2.1.0"
|
"uc.micro": "^2.1.0"
|
||||||
@@ -11951,9 +11951,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/test-exclude/node_modules/brace-expansion": {
|
"node_modules/test-exclude/node_modules/brace-expansion": {
|
||||||
"version": "2.1.4",
|
"version": "2.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz",
|
||||||
"integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==",
|
"integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -12422,9 +12422,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "7.29.0",
|
"version": "7.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-7.30.0.tgz",
|
||||||
"integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==",
|
"integrity": "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
+1
-12
@@ -96,7 +96,6 @@ const EXPORT_DATA_PROPERTIES = [
|
|||||||
"isType3Font",
|
"isType3Font",
|
||||||
"italic",
|
"italic",
|
||||||
"loadedName",
|
"loadedName",
|
||||||
"mimetype",
|
|
||||||
"missingFile",
|
"missingFile",
|
||||||
"name",
|
"name",
|
||||||
"remeasure",
|
"remeasure",
|
||||||
@@ -1050,7 +1049,6 @@ class Font {
|
|||||||
constructor(name, file, properties, evaluatorOptions) {
|
constructor(name, file, properties, evaluatorOptions) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.psName = null;
|
this.psName = null;
|
||||||
this.mimetype = null;
|
|
||||||
this.disableFontFace = evaluatorOptions.disableFontFace;
|
this.disableFontFace = evaluatorOptions.disableFontFace;
|
||||||
this.fontExtraProperties = evaluatorOptions.fontExtraProperties;
|
this.fontExtraProperties = evaluatorOptions.fontExtraProperties;
|
||||||
|
|
||||||
@@ -1165,8 +1163,6 @@ class Font {
|
|||||||
/* falls through */
|
/* falls through */
|
||||||
case "Type1":
|
case "Type1":
|
||||||
case "CIDFontType0":
|
case "CIDFontType0":
|
||||||
this.mimetype = "font/opentype";
|
|
||||||
|
|
||||||
const cff =
|
const cff =
|
||||||
subtype === "Type1C" || subtype === "CIDFontType0C"
|
subtype === "Type1C" || subtype === "CIDFontType0C"
|
||||||
? new CFFFont(file, properties)
|
? new CFFFont(file, properties)
|
||||||
@@ -1181,8 +1177,6 @@ class Font {
|
|||||||
case "OpenType":
|
case "OpenType":
|
||||||
case "TrueType":
|
case "TrueType":
|
||||||
case "CIDFontType2":
|
case "CIDFontType2":
|
||||||
this.mimetype = "font/opentype";
|
|
||||||
|
|
||||||
// Repair the TrueType file. It is can be damaged in the point of
|
// Repair the TrueType file. It is can be damaged in the point of
|
||||||
// view of the sanitizer
|
// view of the sanitizer
|
||||||
data = this.checkAndRepair(name, file, properties);
|
data = this.checkAndRepair(name, file, properties);
|
||||||
@@ -3038,12 +3032,7 @@ class Font {
|
|||||||
if (cid > 0xffff) {
|
if (cid > 0xffff) {
|
||||||
throw new FormatError("Max size of CID is 65,535");
|
throw new FormatError("Max size of CID is 65,535");
|
||||||
}
|
}
|
||||||
let glyphId = -1;
|
const glyphId = isCidToGidMapEmpty ? cid : (cidToGidMap.get(cid) ?? -1);
|
||||||
if (isCidToGidMapEmpty) {
|
|
||||||
glyphId = cid;
|
|
||||||
} else if (cidToGidMap.has(cid)) {
|
|
||||||
glyphId = cidToGidMap.get(cid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glyphId >= 0 && glyphId < numGlyphs && hasGlyph(glyphId)) {
|
if (glyphId >= 0 && glyphId < numGlyphs && hasGlyph(glyphId)) {
|
||||||
charCodeToGlyphId.set(charCode, glyphId);
|
charCodeToGlyphId.set(charCode, glyphId);
|
||||||
|
|||||||
@@ -423,12 +423,13 @@ class FontFaceObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createNativeFontFace() {
|
createNativeFontFace() {
|
||||||
if (!this.data || this.disableFontFace) {
|
const { data } = this; // Get `data` just once, since it's not shadowed.
|
||||||
|
if (!data || this.disableFontFace) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let nativeFontFace;
|
let nativeFontFace;
|
||||||
if (!this.cssFontInfo) {
|
if (!this.cssFontInfo) {
|
||||||
nativeFontFace = new FontFace(this.loadedName, this.data, {});
|
nativeFontFace = new FontFace(this.loadedName, data, {});
|
||||||
} else {
|
} else {
|
||||||
const css = {
|
const css = {
|
||||||
weight: this.cssFontInfo.fontWeight,
|
weight: this.cssFontInfo.fontWeight,
|
||||||
@@ -438,7 +439,7 @@ class FontFaceObject {
|
|||||||
}
|
}
|
||||||
nativeFontFace = new FontFace(
|
nativeFontFace = new FontFace(
|
||||||
serializeFontFamily(this.cssFontInfo.fontFamily),
|
serializeFontFamily(this.cssFontInfo.fontFamily),
|
||||||
this.data,
|
data,
|
||||||
css
|
css
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -452,11 +453,12 @@ class FontFaceObject {
|
|||||||
throw new Error("Not implemented: createFontFaceRule");
|
throw new Error("Not implemented: createFontFaceRule");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.data || this.disableFontFace) {
|
const { data } = this; // Get `data` just once, since it's not shadowed.
|
||||||
|
if (!data || this.disableFontFace) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Add the @font-face rule to the document.
|
// Add the @font-face rule to the document.
|
||||||
const url = `url(data:${this.mimetype};base64,${this.data.toBase64()});`;
|
const url = `url(data:${this.mimetype};base64,${data.toBase64()});`;
|
||||||
let rule;
|
let rule;
|
||||||
if (!this.cssFontInfo) {
|
if (!this.cssFontInfo) {
|
||||||
rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`;
|
rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`;
|
||||||
@@ -567,7 +569,7 @@ class FontFaceObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get mimetype() {
|
get mimetype() {
|
||||||
return this.#fontData.mimetype;
|
return this.missingFile ? null : "font/opentype";
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
|
|||||||
@@ -13,7 +13,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert, BBOX_INIT, FeatureTest, Util } from "../shared/util.js";
|
import {
|
||||||
|
assert,
|
||||||
|
BBOX_INIT,
|
||||||
|
FeatureTest,
|
||||||
|
shadow,
|
||||||
|
Util,
|
||||||
|
} from "../shared/util.js";
|
||||||
import {
|
import {
|
||||||
CSS_FONT_INFO,
|
CSS_FONT_INFO,
|
||||||
FONT_INFO,
|
FONT_INFO,
|
||||||
@@ -47,15 +53,15 @@ class CssFontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get fontFamily() {
|
get fontFamily() {
|
||||||
return this.#readString(0);
|
return shadow(this, "fontFamily", this.#readString(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
get fontWeight() {
|
get fontWeight() {
|
||||||
return this.#readString(1);
|
return shadow(this, "fontWeight", this.#readString(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
get italicAngle() {
|
get italicAngle() {
|
||||||
return this.#readString(2);
|
return shadow(this, "italicAngle", this.#readString(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,19 +81,19 @@ class SystemFontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get css() {
|
get css() {
|
||||||
return this.#readString(0);
|
return shadow(this, "css", this.#readString(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
get loadedName() {
|
get loadedName() {
|
||||||
return this.#readString(1);
|
return shadow(this, "loadedName", this.#readString(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
get baseFontName() {
|
get baseFontName() {
|
||||||
return this.#readString(2);
|
return shadow(this, "baseFontName", this.#readString(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
get src() {
|
get src() {
|
||||||
return this.#readString(3);
|
return shadow(this, "src", this.#readString(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
get style() {
|
get style() {
|
||||||
@@ -95,7 +101,7 @@ class SystemFontInfo {
|
|||||||
offset += 4 + this.#view.getUint32(offset);
|
offset += 4 + this.#view.getUint32(offset);
|
||||||
const style = readString(this.#buffer, this.#view, /* index = */ 0, offset),
|
const style = readString(this.#buffer, this.#view, /* index = */ 0, offset),
|
||||||
weight = readString(this.#buffer, this.#view, /* index = */ 1, offset);
|
weight = readString(this.#buffer, this.#view, /* index = */ 1, offset);
|
||||||
return { style, weight };
|
return shadow(this, "style", { style, weight });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,43 +127,43 @@ class FontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get black() {
|
get black() {
|
||||||
return this.#readBoolean(0);
|
return shadow(this, "black", this.#readBoolean(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
get bold() {
|
get bold() {
|
||||||
return this.#readBoolean(1);
|
return shadow(this, "bold", this.#readBoolean(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
get disableFontFace() {
|
get disableFontFace() {
|
||||||
return this.#readBoolean(2);
|
return shadow(this, "disableFontFace", this.#readBoolean(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
get fontExtraProperties() {
|
get fontExtraProperties() {
|
||||||
return this.#readBoolean(3);
|
return shadow(this, "fontExtraProperties", this.#readBoolean(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
get isInvalidPDFjsFont() {
|
get isInvalidPDFjsFont() {
|
||||||
return this.#readBoolean(4);
|
return shadow(this, "isInvalidPDFjsFont", this.#readBoolean(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
get isType3Font() {
|
get isType3Font() {
|
||||||
return this.#readBoolean(5);
|
return shadow(this, "isType3Font", this.#readBoolean(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
get italic() {
|
get italic() {
|
||||||
return this.#readBoolean(6);
|
return shadow(this, "italic", this.#readBoolean(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
get missingFile() {
|
get missingFile() {
|
||||||
return this.#readBoolean(7);
|
return shadow(this, "missingFile", this.#readBoolean(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
get remeasure() {
|
get remeasure() {
|
||||||
return this.#readBoolean(8);
|
return shadow(this, "remeasure", this.#readBoolean(8));
|
||||||
}
|
}
|
||||||
|
|
||||||
get vertical() {
|
get vertical() {
|
||||||
return this.#readBoolean(9);
|
return shadow(this, "vertical", this.#readBoolean(9));
|
||||||
}
|
}
|
||||||
|
|
||||||
#readNumber(index) {
|
#readNumber(index) {
|
||||||
@@ -166,20 +172,19 @@ class FontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get ascent() {
|
get ascent() {
|
||||||
return this.#readNumber(0);
|
return shadow(this, "ascent", this.#readNumber(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
get descent() {
|
get descent() {
|
||||||
return this.#readNumber(1);
|
return shadow(this, "descent", this.#readNumber(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#readArray(offset, arrLen, lookupName, increment) {
|
#readArray(offset, arrLen, lookupName, increment) {
|
||||||
const len = this.#view.getUint8(offset);
|
const len = this.#view.getUint8(offset++);
|
||||||
if (len === 0) {
|
if (len === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
assert(len === arrLen, "Invalid array length.");
|
assert(len === arrLen, "Invalid array length.");
|
||||||
offset += 1;
|
|
||||||
const arr = new Array(len);
|
const arr = new Array(len);
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
arr[i] = this.#view[lookupName](offset, true);
|
arr[i] = this.#view[lookupName](offset, true);
|
||||||
@@ -189,20 +194,28 @@ class FontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get bbox() {
|
get bbox() {
|
||||||
return this.#readArray(
|
return shadow(
|
||||||
/* offset = */ FONT_INFO.OFFSET_BBOX,
|
this,
|
||||||
/* arrLen = */ 4,
|
"bbox",
|
||||||
/* lookup = */ "getInt16",
|
this.#readArray(
|
||||||
/* increment = */ 2
|
/* offset = */ FONT_INFO.OFFSET_BBOX,
|
||||||
|
/* arrLen = */ 4,
|
||||||
|
/* lookup = */ "getInt16",
|
||||||
|
/* increment = */ 2
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get fontMatrix() {
|
get fontMatrix() {
|
||||||
return this.#readArray(
|
return shadow(
|
||||||
/* offset = */ FONT_INFO.OFFSET_FONT_MATRIX,
|
this,
|
||||||
/* arrLen = */ 6,
|
"fontMatrix",
|
||||||
/* lookup = */ "getFloat64",
|
this.#readArray(
|
||||||
/* increment = */ 8
|
/* offset = */ FONT_INFO.OFFSET_FONT_MATRIX,
|
||||||
|
/* arrLen = */ 6,
|
||||||
|
/* lookup = */ "getFloat64",
|
||||||
|
/* increment = */ 8
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,44 +230,39 @@ class FontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get fallbackName() {
|
get fallbackName() {
|
||||||
return this.#readString(0);
|
return shadow(this, "fallbackName", this.#readString(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
get loadedName() {
|
get loadedName() {
|
||||||
return this.#readString(1);
|
return shadow(this, "loadedName", this.#readString(1));
|
||||||
}
|
|
||||||
|
|
||||||
get mimetype() {
|
|
||||||
return this.#readString(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return this.#readString(3);
|
return shadow(this, "name", this.#readString(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#getDataOffsets() {
|
#getBufferOffset(index) {
|
||||||
let offset = FONT_INFO.OFFSET_STRINGS;
|
let offset = FONT_INFO.OFFSET_STRINGS;
|
||||||
const stringsLength = this.#view.getUint32(offset);
|
// We need to move past any string-data first, hence the `<=` condition.
|
||||||
offset += 4 + stringsLength;
|
for (let i = 0; i <= index; i++) {
|
||||||
const systemFontInfoLength = this.#view.getUint32(offset);
|
offset += 4 + this.#view.getUint32(offset);
|
||||||
offset += 4 + systemFontInfoLength;
|
}
|
||||||
const cssFontInfoLength = this.#view.getUint32(offset);
|
|
||||||
offset += 4 + cssFontInfoLength;
|
|
||||||
const length = this.#view.getUint32(offset);
|
const length = this.#view.getUint32(offset);
|
||||||
|
|
||||||
return { offset, length };
|
return { offset, length };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: This cannot be shadowed, since it may be cleared.
|
||||||
get data() {
|
get data() {
|
||||||
const { offset, length } = this.#getDataOffsets();
|
const { offset, length } = this.#getBufferOffset(2);
|
||||||
return length === 0
|
return !length
|
||||||
? undefined
|
? undefined
|
||||||
: new Uint8Array(this.#buffer, offset + 4, length);
|
: new Uint8Array(this.#buffer, offset + 4, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearData() {
|
clearData() {
|
||||||
const { offset, length } = this.#getDataOffsets();
|
const { offset, length } = this.#getBufferOffset(2);
|
||||||
if (length === 0) {
|
if (!length) {
|
||||||
return; // The data is either not present, or it was previously cleared.
|
return; // The data is either not present, or it was previously cleared.
|
||||||
}
|
}
|
||||||
this.#view.setUint32(offset, 0); // Zero the data-length.
|
this.#view.setUint32(offset, 0); // Zero the data-length.
|
||||||
@@ -265,35 +273,23 @@ class FontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get cssFontInfo() {
|
get cssFontInfo() {
|
||||||
let offset = FONT_INFO.OFFSET_STRINGS;
|
const { offset, length } = this.#getBufferOffset(1);
|
||||||
const stringsLength = this.#view.getUint32(offset);
|
let info = null;
|
||||||
offset += 4 + stringsLength;
|
if (length) {
|
||||||
const systemFontInfoLength = this.#view.getUint32(offset);
|
const data = new Uint8Array(this.#buffer, offset + 4, length).slice();
|
||||||
offset += 4 + systemFontInfoLength;
|
info = new CssFontInfo(data.buffer);
|
||||||
const cssFontInfoLength = this.#view.getUint32(offset);
|
|
||||||
if (cssFontInfoLength === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
const cssFontInfoData = new Uint8Array(cssFontInfoLength);
|
return shadow(this, "cssFontInfo", info);
|
||||||
cssFontInfoData.set(
|
|
||||||
new Uint8Array(this.#buffer, offset + 4, cssFontInfoLength)
|
|
||||||
);
|
|
||||||
return new CssFontInfo(cssFontInfoData.buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get systemFontInfo() {
|
get systemFontInfo() {
|
||||||
let offset = FONT_INFO.OFFSET_STRINGS;
|
const { offset, length } = this.#getBufferOffset(0);
|
||||||
const stringsLength = this.#view.getUint32(offset);
|
let info = null;
|
||||||
offset += 4 + stringsLength;
|
if (length) {
|
||||||
const systemFontInfoLength = this.#view.getUint32(offset);
|
const data = new Uint8Array(this.#buffer, offset + 4, length).slice();
|
||||||
if (systemFontInfoLength === 0) {
|
info = new SystemFontInfo(data.buffer);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
const systemFontInfoData = new Uint8Array(systemFontInfoLength);
|
return shadow(this, "systemFontInfo", info);
|
||||||
systemFontInfoData.set(
|
|
||||||
new Uint8Array(this.#buffer, offset + 4, systemFontInfoLength)
|
|
||||||
);
|
|
||||||
return new SystemFontInfo(systemFontInfoData.buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -836,24 +836,52 @@ class TilingPattern {
|
|||||||
const ySize = dimy2.size;
|
const ySize = dimy2.size;
|
||||||
const tmpCanvas2 = owner.canvasFactory.create(xSize, ySize);
|
const tmpCanvas2 = owner.canvasFactory.create(xSize, ySize);
|
||||||
const tmpCtx2 = tmpCanvas2.context;
|
const tmpCtx2 = tmpCanvas2.context;
|
||||||
const ii = redrawHorizontally ? Math.floor(width / xstep) : 0;
|
// Source rectangles outside the image contribute no pixels.
|
||||||
const jj = redrawVertically ? Math.floor(height / ystep) : 0;
|
const ii = redrawHorizontally
|
||||||
|
? Math.min(Math.floor(width / xstep), Math.ceil(image.width / xSize))
|
||||||
|
: 0;
|
||||||
|
const jj = redrawVertically
|
||||||
|
? Math.min(Math.floor(height / ystep), Math.ceil(image.height / ySize))
|
||||||
|
: 0;
|
||||||
|
|
||||||
// Draw the overlapping parts of the original tile on the new tile.
|
// Fold rows, then columns, to avoid drawing every offset pair.
|
||||||
for (let i = 0; i <= ii; i++) {
|
// Descending indices draw the origin tile last.
|
||||||
for (let j = 0; j <= jj; j++) {
|
let rowSource = image;
|
||||||
tmpCtx2.drawImage(
|
let bandCanvas = null;
|
||||||
|
if (redrawVertically) {
|
||||||
|
bandCanvas = owner.canvasFactory.create(image.width, ySize);
|
||||||
|
const bandCtx = bandCanvas.context;
|
||||||
|
for (let j = jj; j >= 0; j--) {
|
||||||
|
bandCtx.drawImage(
|
||||||
image,
|
image,
|
||||||
xSize * i,
|
0,
|
||||||
ySize * j,
|
ySize * j,
|
||||||
xSize,
|
image.width,
|
||||||
ySize,
|
ySize,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
xSize,
|
image.width,
|
||||||
ySize
|
ySize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
rowSource = bandCanvas.canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = ii; i >= 0; i--) {
|
||||||
|
tmpCtx2.drawImage(
|
||||||
|
rowSource,
|
||||||
|
xSize * i,
|
||||||
|
0,
|
||||||
|
xSize,
|
||||||
|
ySize,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
xSize,
|
||||||
|
ySize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (bandCanvas) {
|
||||||
|
owner.canvasFactory.destroy(bandCanvas);
|
||||||
}
|
}
|
||||||
owner.canvasFactory.destroy(tmpCanvas);
|
owner.canvasFactory.destroy(tmpCanvas);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class FONT_INFO {
|
|||||||
|
|
||||||
static numbers = ["ascent", "descent"];
|
static numbers = ["ascent", "descent"];
|
||||||
|
|
||||||
static strings = ["fallbackName", "loadedName", "mimetype", "name"];
|
static strings = ["fallbackName", "loadedName", "name"];
|
||||||
|
|
||||||
static OFFSET_NUMBERS = Math.ceil((this.bools.length * 2) / 8);
|
static OFFSET_NUMBERS = Math.ceil((this.bools.length * 2) / 8);
|
||||||
|
|
||||||
|
|||||||
@@ -959,3 +959,6 @@
|
|||||||
!nonembedded_type1_tounicode.pdf
|
!nonembedded_type1_tounicode.pdf
|
||||||
!transfer_maps.pdf
|
!transfer_maps.pdf
|
||||||
!resetform_parent.pdf
|
!resetform_parent.pdf
|
||||||
|
!tiling-pattern-tiny-steps.pdf
|
||||||
|
!tiling-pattern-tiny-steps-large.pdf
|
||||||
|
!tiling-pattern-fold-order.pdf
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
%âãÏÓ
|
||||||
|
1 0 obj
|
||||||
|
<< /Type /Catalog /Pages 2 0 R >>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 20 20] /Resources << /Pattern << /P1 4 0 R >> >> /Contents 5 0 R >>
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<< /PatternType 1 /PaintType 1 /TilingType 1 /BBox [0 0 20 20] /XStep 10 /YStep 10 /Resources << >> /Length 49 >>
|
||||||
|
stream
|
||||||
|
1 0 0 rg 0 0 10 10 re f 0 0 1 rg 10 10 10 10 re f
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<< /Length 38 >>
|
||||||
|
stream
|
||||||
|
q /Pattern cs /P1 scn 0 0 20 20 re f Q
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 6
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000015 00000 n
|
||||||
|
0000000064 00000 n
|
||||||
|
0000000121 00000 n
|
||||||
|
0000000248 00000 n
|
||||||
|
0000000444 00000 n
|
||||||
|
trailer
|
||||||
|
<< /Size 6 /Root 1 0 R >>
|
||||||
|
startxref
|
||||||
|
532
|
||||||
|
%%EOF
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
%âãÏÓ
|
||||||
|
1 0 obj
|
||||||
|
<< /Type /Catalog /Pages 2 0 R >>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 1200 1200] /Resources << /Pattern << /P1 4 0 R >> >> /Contents 5 0 R >>
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<< /PatternType 1 /PaintType 1 /TilingType 1 /BBox [0 0 1200 1200] /XStep 0.001 /YStep 0.001 /Resources << >> /Length 26 >>
|
||||||
|
stream
|
||||||
|
q 1100 1100 100 100 re f Q
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<< /Length 42 >>
|
||||||
|
stream
|
||||||
|
q /Pattern cs /P1 scn 0 0 1200 1200 re f Q
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 6
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000015 00000 n
|
||||||
|
0000000064 00000 n
|
||||||
|
0000000121 00000 n
|
||||||
|
0000000252 00000 n
|
||||||
|
0000000435 00000 n
|
||||||
|
trailer
|
||||||
|
<< /Size 6 /Root 1 0 R >>
|
||||||
|
startxref
|
||||||
|
527
|
||||||
|
%%EOF
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
1 0 obj
|
||||||
|
<< /Type /Catalog /Pages 2 0 R >>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 200 200] /Resources << /Pattern << /P1 4 0 R >> >> /Contents 5 0 R >>
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<< /PatternType 1 /PaintType 1 /TilingType 1 /BBox [0 0 10 10] /XStep 0.001 /YStep 0.001 /Resources << >> /Length 19 >>
|
||||||
|
stream
|
||||||
|
q 0 0 10 10 re f Q
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<< /Length 41 >>
|
||||||
|
stream
|
||||||
|
q /Pattern cs /P1 scn 0 0 200 200 re f Q
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 6
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000009 00000 n
|
||||||
|
0000000058 00000 n
|
||||||
|
0000000115 00000 n
|
||||||
|
0000000244 00000 n
|
||||||
|
0000000415 00000 n
|
||||||
|
trailer
|
||||||
|
<< /Size 6 /Root 1 0 R >>
|
||||||
|
startxref
|
||||||
|
505
|
||||||
|
%%EOF
|
||||||
@@ -239,3 +239,89 @@ describe("custom ownerDocument", function () {
|
|||||||
expect(ownerDocument.adoptedStyleSheets.length).toBe(0);
|
expect(ownerDocument.adoptedStyleSheets.length).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("tiling pattern rendering", function () {
|
||||||
|
// The old folding loops required (10 / 0.001 + 1)^2 = 100,020,001 draws.
|
||||||
|
it("does not hang on tiny XStep/YStep steps", async function () {
|
||||||
|
const loadingTask = getDocument(
|
||||||
|
buildGetDocumentParams("tiling-pattern-tiny-steps.pdf")
|
||||||
|
);
|
||||||
|
const doc = await loadingTask.promise;
|
||||||
|
const page = await doc.getPage(1);
|
||||||
|
|
||||||
|
const viewport = page.getViewport({ scale: 1 });
|
||||||
|
const { canvasFactory } = doc;
|
||||||
|
const canvasAndCtx = canvasFactory.create(viewport.width, viewport.height);
|
||||||
|
|
||||||
|
await page.render({
|
||||||
|
canvas: canvasAndCtx.canvas,
|
||||||
|
viewport,
|
||||||
|
}).promise;
|
||||||
|
|
||||||
|
expect(getTopLeftPixel(canvasAndCtx.context)).toEqual({
|
||||||
|
r: 0,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
a: 255,
|
||||||
|
});
|
||||||
|
|
||||||
|
canvasFactory.destroy(canvasAndCtx);
|
||||||
|
await loadingTask.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Only the tile's far 100x100 corner is painted.
|
||||||
|
it("does not hang and keeps far-corner content on a large BBox with tiny steps", async function () {
|
||||||
|
const loadingTask = getDocument(
|
||||||
|
buildGetDocumentParams("tiling-pattern-tiny-steps-large.pdf")
|
||||||
|
);
|
||||||
|
const doc = await loadingTask.promise;
|
||||||
|
const page = await doc.getPage(1);
|
||||||
|
|
||||||
|
const viewport = page.getViewport({ scale: 1 });
|
||||||
|
const { canvasFactory } = doc;
|
||||||
|
const canvasAndCtx = canvasFactory.create(viewport.width, viewport.height);
|
||||||
|
|
||||||
|
await page.render({
|
||||||
|
canvas: canvasAndCtx.canvas,
|
||||||
|
viewport,
|
||||||
|
}).promise;
|
||||||
|
|
||||||
|
expect(getTopLeftPixel(canvasAndCtx.context)).toEqual({
|
||||||
|
r: 0,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
a: 255,
|
||||||
|
});
|
||||||
|
|
||||||
|
canvasFactory.destroy(canvasAndCtx);
|
||||||
|
await loadingTask.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
// The red and blue squares coincide after folding, exposing draw order.
|
||||||
|
it("places the origin tile on top when tiles overlap", async function () {
|
||||||
|
const loadingTask = getDocument(
|
||||||
|
buildGetDocumentParams("tiling-pattern-fold-order.pdf")
|
||||||
|
);
|
||||||
|
const doc = await loadingTask.promise;
|
||||||
|
const page = await doc.getPage(1);
|
||||||
|
|
||||||
|
const viewport = page.getViewport({ scale: 1 });
|
||||||
|
const { canvasFactory } = doc;
|
||||||
|
const canvasAndCtx = canvasFactory.create(viewport.width, viewport.height);
|
||||||
|
|
||||||
|
await page.render({
|
||||||
|
canvas: canvasAndCtx.canvas,
|
||||||
|
viewport,
|
||||||
|
}).promise;
|
||||||
|
|
||||||
|
expect(getTopLeftPixel(canvasAndCtx.context)).toEqual({
|
||||||
|
r: 255,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
a: 255,
|
||||||
|
});
|
||||||
|
|
||||||
|
canvasFactory.destroy(canvasAndCtx);
|
||||||
|
await loadingTask.destroy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ describe("obj_bin_transform", function () {
|
|||||||
fontMatrix: [1, 1, 1, 1, 1, 1],
|
fontMatrix: [1, 1, 1, 1, 1, 1],
|
||||||
fallbackName: "string",
|
fallbackName: "string",
|
||||||
loadedName: "string",
|
loadedName: "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",
|
||||||
@@ -124,7 +123,7 @@ describe("obj_bin_transform", function () {
|
|||||||
|
|
||||||
describe("FontInfo", function () {
|
describe("FontInfo", function () {
|
||||||
it("must roundtrip correctly for FontInfo", function () {
|
it("must roundtrip correctly for FontInfo", function () {
|
||||||
let sizeEstimate = 77; // fixed offset until the strings
|
let sizeEstimate = 67; // fixed offset until the strings
|
||||||
const { encoder } = InfoUtils;
|
const { encoder } = InfoUtils;
|
||||||
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
|
||||||
@@ -148,7 +147,6 @@ describe("obj_bin_transform", function () {
|
|||||||
expect(deserialized.fontMatrix).toEqual([1, 1, 1, 1, 1, 1]);
|
expect(deserialized.fontMatrix).toEqual([1, 1, 1, 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.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,
|
||||||
|
|||||||
Reference in New Issue
Block a user