Add support for missing appearances for hightlights, strikeout, squiggly and underline annotations.
This commit is contained in:
parent
7df8aa34a5
commit
65ecd981fe
@ -199,8 +199,13 @@ function getQuadPoints(dict, rect) {
|
|||||||
const y = quadPoints[j + 1];
|
const y = quadPoints[j + 1];
|
||||||
|
|
||||||
// The quadpoints should be ignored if any coordinate in the array
|
// The quadpoints should be ignored if any coordinate in the array
|
||||||
// lies outside the region specified by the rectangle.
|
// lies outside the region specified by the rectangle. The rectangle
|
||||||
if (x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3]) {
|
// can be `null` for markup annotations since their rectangle may be
|
||||||
|
// incorrect (fixes bug 1538111).
|
||||||
|
if (
|
||||||
|
rect !== null &&
|
||||||
|
(x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3])
|
||||||
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
quadPointsLists[i].push({ x, y });
|
quadPointsLists[i].push({ x, y });
|
||||||
@ -791,6 +796,68 @@ class MarkupAnnotation extends Annotation {
|
|||||||
setCreationDate(creationDate) {
|
setCreationDate(creationDate) {
|
||||||
this.creationDate = isString(creationDate) ? creationDate : null;
|
this.creationDate = isString(creationDate) ? creationDate : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_setDefaultAppearance({
|
||||||
|
xref,
|
||||||
|
extra,
|
||||||
|
strokeColor,
|
||||||
|
fillColor,
|
||||||
|
blendMode,
|
||||||
|
pointsCallback,
|
||||||
|
}) {
|
||||||
|
let minX = Number.MAX_VALUE;
|
||||||
|
let minY = Number.MAX_VALUE;
|
||||||
|
let maxX = Number.MIN_VALUE;
|
||||||
|
let maxY = Number.MIN_VALUE;
|
||||||
|
|
||||||
|
const buffer = ["q"];
|
||||||
|
if (extra) {
|
||||||
|
buffer.push(extra);
|
||||||
|
}
|
||||||
|
if (strokeColor) {
|
||||||
|
buffer.push(`${strokeColor[0]} ${strokeColor[1]} ${strokeColor[2]} RG`);
|
||||||
|
}
|
||||||
|
if (fillColor) {
|
||||||
|
buffer.push(`${fillColor[0]} ${fillColor[1]} ${fillColor[2]} rg`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const points of this.data.quadPoints) {
|
||||||
|
const [mX, MX, mY, MY] = pointsCallback(buffer, points);
|
||||||
|
minX = Math.min(minX, mX);
|
||||||
|
maxX = Math.max(maxX, MX);
|
||||||
|
minY = Math.min(minY, mY);
|
||||||
|
maxY = Math.max(maxY, MY);
|
||||||
|
}
|
||||||
|
buffer.push("Q");
|
||||||
|
|
||||||
|
const formDict = new Dict(xref);
|
||||||
|
const appearanceStreamDict = new Dict(xref);
|
||||||
|
appearanceStreamDict.set("Subtype", Name.get("Form"));
|
||||||
|
|
||||||
|
const appearanceStream = new StringStream(buffer.join(" "));
|
||||||
|
appearanceStream.dict = appearanceStreamDict;
|
||||||
|
formDict.set("Fm0", appearanceStream);
|
||||||
|
|
||||||
|
const gsDict = new Dict(xref);
|
||||||
|
if (blendMode) {
|
||||||
|
gsDict.set("BM", Name.get(blendMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
const stateDict = new Dict(xref);
|
||||||
|
stateDict.set("GS0", gsDict);
|
||||||
|
|
||||||
|
const resources = new Dict(xref);
|
||||||
|
resources.set("ExtGState", stateDict);
|
||||||
|
resources.set("XObject", formDict);
|
||||||
|
|
||||||
|
const appearanceDict = new Dict(xref);
|
||||||
|
appearanceDict.set("Resources", resources);
|
||||||
|
const bbox = (this.data.rect = [minX, minY, maxX, maxY]);
|
||||||
|
appearanceDict.set("BBox", bbox);
|
||||||
|
|
||||||
|
this.appearance = new StringStream("/GS0 gs /Fm0 Do");
|
||||||
|
this.appearance.dict = appearanceDict;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WidgetAnnotation extends Annotation {
|
class WidgetAnnotation extends Annotation {
|
||||||
@ -1854,9 +1921,28 @@ class HighlightAnnotation extends MarkupAnnotation {
|
|||||||
|
|
||||||
this.data.annotationType = AnnotationType.HIGHLIGHT;
|
this.data.annotationType = AnnotationType.HIGHLIGHT;
|
||||||
|
|
||||||
const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
|
const quadPoints = getQuadPoints(parameters.dict, null);
|
||||||
if (quadPoints) {
|
if (quadPoints) {
|
||||||
this.data.quadPoints = quadPoints;
|
this.data.quadPoints = quadPoints;
|
||||||
|
if (!this.appearance) {
|
||||||
|
// Default color is yellow in Acrobat Reader
|
||||||
|
const fillColor = this.color
|
||||||
|
? Array.from(this.color).map(c => c / 255)
|
||||||
|
: [1, 1, 0];
|
||||||
|
this._setDefaultAppearance({
|
||||||
|
xref: parameters.xref,
|
||||||
|
fillColor,
|
||||||
|
blendMode: "Multiply",
|
||||||
|
pointsCallback: (buffer, points) => {
|
||||||
|
buffer.push(`${points[0].x} ${points[0].y} m`);
|
||||||
|
buffer.push(`${points[1].x} ${points[1].y} l`);
|
||||||
|
buffer.push(`${points[3].x} ${points[3].y} l`);
|
||||||
|
buffer.push(`${points[2].x} ${points[2].y} l`);
|
||||||
|
buffer.push("f");
|
||||||
|
return [points[0].x, points[1].x, points[3].y, points[1].y];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1867,9 +1953,26 @@ class UnderlineAnnotation extends MarkupAnnotation {
|
|||||||
|
|
||||||
this.data.annotationType = AnnotationType.UNDERLINE;
|
this.data.annotationType = AnnotationType.UNDERLINE;
|
||||||
|
|
||||||
const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
|
const quadPoints = getQuadPoints(parameters.dict, null);
|
||||||
if (quadPoints) {
|
if (quadPoints) {
|
||||||
this.data.quadPoints = quadPoints;
|
this.data.quadPoints = quadPoints;
|
||||||
|
if (!this.appearance) {
|
||||||
|
// Default color is black
|
||||||
|
const strokeColor = this.color
|
||||||
|
? Array.from(this.color).map(c => c / 255)
|
||||||
|
: [0, 0, 0];
|
||||||
|
this._setDefaultAppearance({
|
||||||
|
xref: parameters.xref,
|
||||||
|
extra: "[] 0 d 1 w",
|
||||||
|
strokeColor,
|
||||||
|
pointsCallback: (buffer, points) => {
|
||||||
|
buffer.push(`${points[2].x} ${points[2].y} m`);
|
||||||
|
buffer.push(`${points[3].x} ${points[3].y} l`);
|
||||||
|
buffer.push("S");
|
||||||
|
return [points[0].x, points[1].x, points[3].y, points[1].y];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1880,9 +1983,35 @@ class SquigglyAnnotation extends MarkupAnnotation {
|
|||||||
|
|
||||||
this.data.annotationType = AnnotationType.SQUIGGLY;
|
this.data.annotationType = AnnotationType.SQUIGGLY;
|
||||||
|
|
||||||
const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
|
const quadPoints = getQuadPoints(parameters.dict, null);
|
||||||
if (quadPoints) {
|
if (quadPoints) {
|
||||||
this.data.quadPoints = quadPoints;
|
this.data.quadPoints = quadPoints;
|
||||||
|
if (!this.appearance) {
|
||||||
|
// Default color is black
|
||||||
|
const strokeColor = this.color
|
||||||
|
? Array.from(this.color).map(c => c / 255)
|
||||||
|
: [0, 0, 0];
|
||||||
|
this._setDefaultAppearance({
|
||||||
|
xref: parameters.xref,
|
||||||
|
extra: "[] 0 d 1 w",
|
||||||
|
strokeColor,
|
||||||
|
pointsCallback: (buffer, points) => {
|
||||||
|
const dy = (points[0].y - points[2].y) / 6;
|
||||||
|
let shift = dy;
|
||||||
|
let x = points[2].x;
|
||||||
|
const y = points[2].y;
|
||||||
|
const xEnd = points[3].x;
|
||||||
|
buffer.push(`${x} ${y + shift} m`);
|
||||||
|
do {
|
||||||
|
x += 2;
|
||||||
|
shift = shift === 0 ? dy : 0;
|
||||||
|
buffer.push(`${x} ${y + shift} l`);
|
||||||
|
} while (x < xEnd);
|
||||||
|
buffer.push("S");
|
||||||
|
return [points[2].x, xEnd, y - 2 * dy, y + 2 * dy];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1893,9 +2022,32 @@ class StrikeOutAnnotation extends MarkupAnnotation {
|
|||||||
|
|
||||||
this.data.annotationType = AnnotationType.STRIKEOUT;
|
this.data.annotationType = AnnotationType.STRIKEOUT;
|
||||||
|
|
||||||
const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
|
const quadPoints = getQuadPoints(parameters.dict, null);
|
||||||
if (quadPoints) {
|
if (quadPoints) {
|
||||||
this.data.quadPoints = quadPoints;
|
this.data.quadPoints = quadPoints;
|
||||||
|
if (!this.appearance) {
|
||||||
|
// Default color is black
|
||||||
|
const strokeColor = this.color
|
||||||
|
? Array.from(this.color).map(c => c / 255)
|
||||||
|
: [0, 0, 0];
|
||||||
|
this._setDefaultAppearance({
|
||||||
|
xref: parameters.xref,
|
||||||
|
extra: "[] 0 d 1 w",
|
||||||
|
strokeColor,
|
||||||
|
pointsCallback: (buffer, points) => {
|
||||||
|
buffer.push(
|
||||||
|
`${(points[0].x + points[2].x) / 2}` +
|
||||||
|
` ${(points[0].y + points[2].y) / 2} m`
|
||||||
|
);
|
||||||
|
buffer.push(
|
||||||
|
`${(points[1].x + points[3].x) / 2}` +
|
||||||
|
` ${(points[1].y + points[3].y) / 2} l`
|
||||||
|
);
|
||||||
|
buffer.push("S");
|
||||||
|
return [points[0].x, points[1].x, points[3].y, points[1].y];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
test/pdfs/.gitignore
vendored
5
test/pdfs/.gitignore
vendored
@ -113,6 +113,7 @@
|
|||||||
!bug1245391_reduced.pdf
|
!bug1245391_reduced.pdf
|
||||||
!bug1252420.pdf
|
!bug1252420.pdf
|
||||||
!bug1513120_reduced.pdf
|
!bug1513120_reduced.pdf
|
||||||
|
!bug1538111.pdf
|
||||||
!bug1552113.pdf
|
!bug1552113.pdf
|
||||||
!issue9949.pdf
|
!issue9949.pdf
|
||||||
!bug1308536.pdf
|
!bug1308536.pdf
|
||||||
@ -359,10 +360,14 @@
|
|||||||
!issue9278.pdf
|
!issue9278.pdf
|
||||||
!annotation-text-without-popup.pdf
|
!annotation-text-without-popup.pdf
|
||||||
!annotation-underline.pdf
|
!annotation-underline.pdf
|
||||||
|
!annotation-underline-without-appearance.pdf
|
||||||
!issue269_2.pdf
|
!issue269_2.pdf
|
||||||
!annotation-strikeout.pdf
|
!annotation-strikeout.pdf
|
||||||
|
!annotation-strikeout-without-appearance.pdf
|
||||||
!annotation-squiggly.pdf
|
!annotation-squiggly.pdf
|
||||||
|
!annotation-squiggly-without-appearance.pdf
|
||||||
!annotation-highlight.pdf
|
!annotation-highlight.pdf
|
||||||
|
!annotation-highlight-without-appearance.pdf
|
||||||
!annotation-freetext.pdf
|
!annotation-freetext.pdf
|
||||||
!annotation-line.pdf
|
!annotation-line.pdf
|
||||||
!annotation-square-circle.pdf
|
!annotation-square-circle.pdf
|
||||||
|
BIN
test/pdfs/annotation-highlight-without-appearance.pdf
Normal file
BIN
test/pdfs/annotation-highlight-without-appearance.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/annotation-squiggly-without-appearance.pdf
Normal file
BIN
test/pdfs/annotation-squiggly-without-appearance.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/annotation-strikeout-without-appearance.pdf
Normal file
BIN
test/pdfs/annotation-strikeout-without-appearance.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/annotation-underline-without-appearance.pdf
Normal file
BIN
test/pdfs/annotation-underline-without-appearance.pdf
Normal file
Binary file not shown.
108
test/pdfs/bug1538111.pdf
Normal file
108
test/pdfs/bug1538111.pdf
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
% ò¤ô
|
||||||
|
|
||||||
|
1 0 obj <<
|
||||||
|
/Type /Catalog
|
||||||
|
/Pages 2 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj <<
|
||||||
|
/Type /Pages
|
||||||
|
/Count 1
|
||||||
|
/Kids [ 3 0 R ]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj <<
|
||||||
|
/Type /Page
|
||||||
|
/Parent 2 0 R
|
||||||
|
/MediaBox [0 0 595 842]
|
||||||
|
/Annots [
|
||||||
|
4 0 R
|
||||||
|
5 0 R
|
||||||
|
6 0 R
|
||||||
|
7 0 R
|
||||||
|
]
|
||||||
|
/Tabs /R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Highlight
|
||||||
|
/Rect [ 108 602 506 640 ]
|
||||||
|
/NM (Hilight-1)
|
||||||
|
/F 4
|
||||||
|
/QuadPoints [
|
||||||
|
107.7896 639.9486 505.8939 639.9486 107.7896 629.1634 505.8939 629.1634
|
||||||
|
107.7896 626.2871 505.8939 626.2871 107.7896 615.5011 505.8939 615.5011
|
||||||
|
107.7896 612.6248 380.1389 612.6248 107.7896 601.8397 380.1389 601.8397
|
||||||
|
]
|
||||||
|
/C [ 1 1 0 ]
|
||||||
|
/Contents ()
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
5 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Underline
|
||||||
|
/Rect [ 108 552 506 590 ]
|
||||||
|
/NM (Underline-1)
|
||||||
|
/F 4
|
||||||
|
/QuadPoints [
|
||||||
|
107.7896 589.9486 505.8939 589.9486 107.7896 579.1634 505.8939 579.1634
|
||||||
|
107.7896 576.2871 505.8939 576.2871 107.7896 565.5011 505.8939 565.5011
|
||||||
|
107.7896 562.6248 380.1389 562.6248 107.7896 551.8397 380.1389 551.8397
|
||||||
|
]
|
||||||
|
/C [ 0 0 0 ]
|
||||||
|
/Contents ()
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
6 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Squiggly
|
||||||
|
/Rect [ 108 502 506 540 ]
|
||||||
|
/NM (Squiggly-1)
|
||||||
|
/F 4
|
||||||
|
/QuadPoints [
|
||||||
|
107.7896 539.9486 505.8939 539.9486 107.7896 529.1634 505.8939 529.1634
|
||||||
|
107.7896 526.2871 505.8939 526.2871 107.7896 515.5011 505.8939 515.5011
|
||||||
|
107.7896 512.6248 380.1389 512.6248 107.7896 501.8397 380.1389 501.8397
|
||||||
|
]
|
||||||
|
/C [ 0 0 0 ]
|
||||||
|
/Contents ()
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
7 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /StrikeOut
|
||||||
|
/Rect [ 108 452 506 490 ]
|
||||||
|
/NM (StrikeOut-1)
|
||||||
|
/F 4
|
||||||
|
/QuadPoints [
|
||||||
|
107.7896 489.9486 505.8939 489.9486 107.7896 479.1634 505.8939 479.1634
|
||||||
|
107.7896 476.2871 505.8939 476.2871 107.7896 465.5011 505.8939 465.5011
|
||||||
|
107.7896 462.6248 380.1389 462.6248 107.7896 451.8397 380.1389 451.8397
|
||||||
|
]
|
||||||
|
/C [ 0 0 0 ]
|
||||||
|
/Contents ()
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 8
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000016 00000 n
|
||||||
|
0000000070 00000 n
|
||||||
|
0000000136 00000 n
|
||||||
|
0000000281 00000 n
|
||||||
|
0000000671 00000 n
|
||||||
|
0000001063 00000 n
|
||||||
|
0000001453 00000 n
|
||||||
|
trailer<< /Root 1 0 R /Size 8 >>
|
||||||
|
startxref
|
||||||
|
1845
|
||||||
|
%%EOF
|
@ -764,6 +764,13 @@
|
|||||||
"annotations": true,
|
"annotations": true,
|
||||||
"about": "Annotation with (unsupported) file:// URL."
|
"about": "Annotation with (unsupported) file:// URL."
|
||||||
},
|
},
|
||||||
|
{ "id": "bug1538111",
|
||||||
|
"file": "pdfs/bug1538111.pdf",
|
||||||
|
"md5": "3f3635cfc25d132fb1054042e520e297",
|
||||||
|
"rounds": 1,
|
||||||
|
"annotations": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "bug1552113",
|
{ "id": "bug1552113",
|
||||||
"file": "pdfs/bug1552113.pdf",
|
"file": "pdfs/bug1552113.pdf",
|
||||||
"md5": "dafb7ba1328e8deaab2e3619c94bf974",
|
"md5": "dafb7ba1328e8deaab2e3619c94bf974",
|
||||||
@ -4378,6 +4385,13 @@
|
|||||||
"type": "eq",
|
"type": "eq",
|
||||||
"annotations": true
|
"annotations": true
|
||||||
},
|
},
|
||||||
|
{ "id": "annotation-underline-without-appearance",
|
||||||
|
"file": "pdfs/annotation-underline-without-appearance.pdf",
|
||||||
|
"md5": "dd5be5e9a8e6bdbf67c175ca170f7cb7",
|
||||||
|
"rounds": 1,
|
||||||
|
"annotations": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "annotation-strikeout",
|
{ "id": "annotation-strikeout",
|
||||||
"file": "pdfs/annotation-strikeout.pdf",
|
"file": "pdfs/annotation-strikeout.pdf",
|
||||||
"md5": "6624e6b5bedd2f2855b6ab12bbf93c57",
|
"md5": "6624e6b5bedd2f2855b6ab12bbf93c57",
|
||||||
@ -4385,6 +4399,13 @@
|
|||||||
"type": "eq",
|
"type": "eq",
|
||||||
"annotations": true
|
"annotations": true
|
||||||
},
|
},
|
||||||
|
{ "id": "annotation-strikeout-without-appearance",
|
||||||
|
"file": "pdfs/annotation-strikeout-without-appearance.pdf",
|
||||||
|
"md5": "1dc751ab83e8deb3094bfc580289b097",
|
||||||
|
"rounds": 1,
|
||||||
|
"annotations": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "annotation-squiggly",
|
{ "id": "annotation-squiggly",
|
||||||
"file": "pdfs/annotation-squiggly.pdf",
|
"file": "pdfs/annotation-squiggly.pdf",
|
||||||
"md5": "38661e731ac6c525af5894d2d20c6e71",
|
"md5": "38661e731ac6c525af5894d2d20c6e71",
|
||||||
@ -4392,6 +4413,13 @@
|
|||||||
"type": "eq",
|
"type": "eq",
|
||||||
"annotations": true
|
"annotations": true
|
||||||
},
|
},
|
||||||
|
{ "id": "annotation-squiggly-without-appearance",
|
||||||
|
"file": "pdfs/annotation-squiggly-without-appearance.pdf",
|
||||||
|
"md5": "6546f22a06a5e51d0e835c677cdbc705",
|
||||||
|
"rounds": 1,
|
||||||
|
"annotations": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "annotation-highlight",
|
{ "id": "annotation-highlight",
|
||||||
"file": "pdfs/annotation-highlight.pdf",
|
"file": "pdfs/annotation-highlight.pdf",
|
||||||
"md5": "e13e198e3a69c32dc9ebdc704d3105e1",
|
"md5": "e13e198e3a69c32dc9ebdc704d3105e1",
|
||||||
@ -4399,6 +4427,13 @@
|
|||||||
"type": "eq",
|
"type": "eq",
|
||||||
"annotations": true
|
"annotations": true
|
||||||
},
|
},
|
||||||
|
{ "id": "annotation-highlight-without-appearance",
|
||||||
|
"file": "pdfs/annotation-highlight-without-appearance.pdf",
|
||||||
|
"md5": "a1f2811324fa1ff0c9f1778697413dad",
|
||||||
|
"rounds": 1,
|
||||||
|
"annotations": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "annotation-freetext",
|
{ "id": "annotation-freetext",
|
||||||
"file": "pdfs/annotation-freetext.pdf",
|
"file": "pdfs/annotation-freetext.pdf",
|
||||||
"md5": "6ca19ce632ead3aed08f22e588510e2f",
|
"md5": "6ca19ce632ead3aed08f22e588510e2f",
|
||||||
|
Loading…
Reference in New Issue
Block a user