Support strokeAlpha/fillAlpha when creating a fallback appearance stream (issue 6810)
This fixes the colours, by respecting the strokeAlpha/fillAlpha-values, for a couple of Annotations in the PDF document from issue 13447.[1] --- [1] Some of the annotations still won't render at all, when compared with Adobe Reader, but that could/should probably be handled separately.
This commit is contained in:
parent
f587d5998e
commit
a6447f2ca2
@ -1070,6 +1070,8 @@ class MarkupAnnotation extends Annotation {
|
|||||||
strokeColor,
|
strokeColor,
|
||||||
fillColor,
|
fillColor,
|
||||||
blendMode,
|
blendMode,
|
||||||
|
strokeAlpha,
|
||||||
|
fillAlpha,
|
||||||
pointsCallback,
|
pointsCallback,
|
||||||
}) {
|
}) {
|
||||||
let minX = Number.MAX_VALUE;
|
let minX = Number.MAX_VALUE;
|
||||||
@ -1124,6 +1126,12 @@ class MarkupAnnotation extends Annotation {
|
|||||||
if (blendMode) {
|
if (blendMode) {
|
||||||
gsDict.set("BM", Name.get(blendMode));
|
gsDict.set("BM", Name.get(blendMode));
|
||||||
}
|
}
|
||||||
|
if (typeof strokeAlpha === "number") {
|
||||||
|
gsDict.set("CA", strokeAlpha);
|
||||||
|
}
|
||||||
|
if (typeof fillAlpha === "number") {
|
||||||
|
gsDict.set("ca", fillAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
const stateDict = new Dict(xref);
|
const stateDict = new Dict(xref);
|
||||||
stateDict.set("GS0", gsDict);
|
stateDict.set("GS0", gsDict);
|
||||||
@ -2400,6 +2408,19 @@ class LineAnnotation extends MarkupAnnotation {
|
|||||||
const strokeColor = this.color
|
const strokeColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [0, 0, 0];
|
: [0, 0, 0];
|
||||||
|
const strokeAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
|
// The default fill color is transparent. Setting the fill colour is
|
||||||
|
// necessary if/when we want to add support for non-default line endings.
|
||||||
|
let fillColor = null,
|
||||||
|
interiorColor = parameters.dict.getArray("IC");
|
||||||
|
if (interiorColor) {
|
||||||
|
interiorColor = getRgbColor(interiorColor);
|
||||||
|
fillColor = interiorColor
|
||||||
|
? Array.from(interiorColor).map(c => c / 255)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
const fillAlpha = fillColor ? strokeAlpha : null;
|
||||||
|
|
||||||
const borderWidth = this.borderStyle.width;
|
const borderWidth = this.borderStyle.width;
|
||||||
|
|
||||||
@ -2418,6 +2439,9 @@ class LineAnnotation extends MarkupAnnotation {
|
|||||||
xref: parameters.xref,
|
xref: parameters.xref,
|
||||||
extra: `${borderWidth} w`,
|
extra: `${borderWidth} w`,
|
||||||
strokeColor,
|
strokeColor,
|
||||||
|
fillColor,
|
||||||
|
strokeAlpha,
|
||||||
|
fillAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
buffer.push(
|
buffer.push(
|
||||||
`${lineCoordinates[0]} ${lineCoordinates[1]} m`,
|
`${lineCoordinates[0]} ${lineCoordinates[1]} m`,
|
||||||
@ -2447,22 +2471,26 @@ class SquareAnnotation extends MarkupAnnotation {
|
|||||||
const strokeColor = this.color
|
const strokeColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [0, 0, 0];
|
: [0, 0, 0];
|
||||||
|
const strokeAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
// The default fill color is transparent.
|
// The default fill color is transparent.
|
||||||
let fillColor = null;
|
let fillColor = null,
|
||||||
let interiorColor = parameters.dict.getArray("IC");
|
interiorColor = parameters.dict.getArray("IC");
|
||||||
if (interiorColor) {
|
if (interiorColor) {
|
||||||
interiorColor = getRgbColor(interiorColor);
|
interiorColor = getRgbColor(interiorColor);
|
||||||
fillColor = interiorColor
|
fillColor = interiorColor
|
||||||
? Array.from(interiorColor).map(c => c / 255)
|
? Array.from(interiorColor).map(c => c / 255)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
const fillAlpha = fillColor ? strokeAlpha : null;
|
||||||
|
|
||||||
this._setDefaultAppearance({
|
this._setDefaultAppearance({
|
||||||
xref: parameters.xref,
|
xref: parameters.xref,
|
||||||
extra: `${this.borderStyle.width} w`,
|
extra: `${this.borderStyle.width} w`,
|
||||||
strokeColor,
|
strokeColor,
|
||||||
fillColor,
|
fillColor,
|
||||||
|
strokeAlpha,
|
||||||
|
fillAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
const x = points[2].x + this.borderStyle.width / 2;
|
const x = points[2].x + this.borderStyle.width / 2;
|
||||||
const y = points[2].y + this.borderStyle.width / 2;
|
const y = points[2].y + this.borderStyle.width / 2;
|
||||||
@ -2492,6 +2520,7 @@ class CircleAnnotation extends MarkupAnnotation {
|
|||||||
const strokeColor = this.color
|
const strokeColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [0, 0, 0];
|
: [0, 0, 0];
|
||||||
|
const strokeAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
// The default fill color is transparent.
|
// The default fill color is transparent.
|
||||||
let fillColor = null;
|
let fillColor = null;
|
||||||
@ -2502,6 +2531,7 @@ class CircleAnnotation extends MarkupAnnotation {
|
|||||||
? Array.from(interiorColor).map(c => c / 255)
|
? Array.from(interiorColor).map(c => c / 255)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
const fillAlpha = fillColor ? strokeAlpha : null;
|
||||||
|
|
||||||
// Circles are approximated by Bézier curves with four segments since
|
// Circles are approximated by Bézier curves with four segments since
|
||||||
// there is no circle primitive in the PDF specification. For the control
|
// there is no circle primitive in the PDF specification. For the control
|
||||||
@ -2513,6 +2543,8 @@ class CircleAnnotation extends MarkupAnnotation {
|
|||||||
extra: `${this.borderStyle.width} w`,
|
extra: `${this.borderStyle.width} w`,
|
||||||
strokeColor,
|
strokeColor,
|
||||||
fillColor,
|
fillColor,
|
||||||
|
strokeAlpha,
|
||||||
|
fillAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
const x0 = points[0].x + this.borderStyle.width / 2;
|
const x0 = points[0].x + this.borderStyle.width / 2;
|
||||||
const y0 = points[0].y - this.borderStyle.width / 2;
|
const y0 = points[0].y - this.borderStyle.width / 2;
|
||||||
@ -2569,6 +2601,7 @@ class PolylineAnnotation extends MarkupAnnotation {
|
|||||||
const strokeColor = this.color
|
const strokeColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [0, 0, 0];
|
: [0, 0, 0];
|
||||||
|
const strokeAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
const borderWidth = this.borderStyle.width || 1;
|
const borderWidth = this.borderStyle.width || 1;
|
||||||
|
|
||||||
@ -2576,6 +2609,7 @@ class PolylineAnnotation extends MarkupAnnotation {
|
|||||||
xref: parameters.xref,
|
xref: parameters.xref,
|
||||||
extra: `${borderWidth} w`,
|
extra: `${borderWidth} w`,
|
||||||
strokeColor,
|
strokeColor,
|
||||||
|
strokeAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
const vertices = this.data.vertices;
|
const vertices = this.data.vertices;
|
||||||
for (let i = 0, ii = vertices.length; i < ii; i++) {
|
for (let i = 0, ii = vertices.length; i < ii; i++) {
|
||||||
@ -2639,6 +2673,7 @@ class InkAnnotation extends MarkupAnnotation {
|
|||||||
const strokeColor = this.color
|
const strokeColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [0, 0, 0];
|
: [0, 0, 0];
|
||||||
|
const strokeAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
const borderWidth = this.borderStyle.width || 1;
|
const borderWidth = this.borderStyle.width || 1;
|
||||||
|
|
||||||
@ -2646,6 +2681,7 @@ class InkAnnotation extends MarkupAnnotation {
|
|||||||
xref: parameters.xref,
|
xref: parameters.xref,
|
||||||
extra: `${borderWidth} w`,
|
extra: `${borderWidth} w`,
|
||||||
strokeColor,
|
strokeColor,
|
||||||
|
strokeAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
// According to the specification, see "12.5.6.13 Ink Annotations":
|
// According to the specification, see "12.5.6.13 Ink Annotations":
|
||||||
// When drawn, the points shall be connected by straight lines or
|
// When drawn, the points shall be connected by straight lines or
|
||||||
@ -2681,10 +2717,13 @@ class HighlightAnnotation extends MarkupAnnotation {
|
|||||||
const fillColor = this.color
|
const fillColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [1, 1, 0];
|
: [1, 1, 0];
|
||||||
|
const fillAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
this._setDefaultAppearance({
|
this._setDefaultAppearance({
|
||||||
xref: parameters.xref,
|
xref: parameters.xref,
|
||||||
fillColor,
|
fillColor,
|
||||||
blendMode: "Multiply",
|
blendMode: "Multiply",
|
||||||
|
fillAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
buffer.push(
|
buffer.push(
|
||||||
`${points[0].x} ${points[0].y} m`,
|
`${points[0].x} ${points[0].y} m`,
|
||||||
@ -2718,10 +2757,13 @@ class UnderlineAnnotation extends MarkupAnnotation {
|
|||||||
const strokeColor = this.color
|
const strokeColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [0, 0, 0];
|
: [0, 0, 0];
|
||||||
|
const strokeAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
this._setDefaultAppearance({
|
this._setDefaultAppearance({
|
||||||
xref: parameters.xref,
|
xref: parameters.xref,
|
||||||
extra: "[] 0 d 1 w",
|
extra: "[] 0 d 1 w",
|
||||||
strokeColor,
|
strokeColor,
|
||||||
|
strokeAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
buffer.push(
|
buffer.push(
|
||||||
`${points[2].x} ${points[2].y} m`,
|
`${points[2].x} ${points[2].y} m`,
|
||||||
@ -2754,10 +2796,13 @@ class SquigglyAnnotation extends MarkupAnnotation {
|
|||||||
const strokeColor = this.color
|
const strokeColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [0, 0, 0];
|
: [0, 0, 0];
|
||||||
|
const strokeAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
this._setDefaultAppearance({
|
this._setDefaultAppearance({
|
||||||
xref: parameters.xref,
|
xref: parameters.xref,
|
||||||
extra: "[] 0 d 1 w",
|
extra: "[] 0 d 1 w",
|
||||||
strokeColor,
|
strokeColor,
|
||||||
|
strokeAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
const dy = (points[0].y - points[2].y) / 6;
|
const dy = (points[0].y - points[2].y) / 6;
|
||||||
let shift = dy;
|
let shift = dy;
|
||||||
@ -2797,10 +2842,13 @@ class StrikeOutAnnotation extends MarkupAnnotation {
|
|||||||
const strokeColor = this.color
|
const strokeColor = this.color
|
||||||
? Array.from(this.color).map(c => c / 255)
|
? Array.from(this.color).map(c => c / 255)
|
||||||
: [0, 0, 0];
|
: [0, 0, 0];
|
||||||
|
const strokeAlpha = parameters.dict.get("CA");
|
||||||
|
|
||||||
this._setDefaultAppearance({
|
this._setDefaultAppearance({
|
||||||
xref: parameters.xref,
|
xref: parameters.xref,
|
||||||
extra: "[] 0 d 1 w",
|
extra: "[] 0 d 1 w",
|
||||||
strokeColor,
|
strokeColor,
|
||||||
|
strokeAlpha,
|
||||||
pointsCallback: (buffer, points) => {
|
pointsCallback: (buffer, points) => {
|
||||||
buffer.push(
|
buffer.push(
|
||||||
`${(points[0].x + points[2].x) / 2} ` +
|
`${(points[0].x + points[2].x) / 2} ` +
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -124,6 +124,7 @@
|
|||||||
!bug1068432.pdf
|
!bug1068432.pdf
|
||||||
!issue12295.pdf
|
!issue12295.pdf
|
||||||
!bug1146106.pdf
|
!bug1146106.pdf
|
||||||
|
!issue13447.pdf
|
||||||
!bug1245391_reduced.pdf
|
!bug1245391_reduced.pdf
|
||||||
!bug1252420.pdf
|
!bug1252420.pdf
|
||||||
!bug1513120_reduced.pdf
|
!bug1513120_reduced.pdf
|
||||||
|
BIN
test/pdfs/issue13447.pdf
Normal file
BIN
test/pdfs/issue13447.pdf
Normal file
Binary file not shown.
@ -115,6 +115,19 @@
|
|||||||
"type": "eq",
|
"type": "eq",
|
||||||
"about": "Causes cmap to be created with invalid glyph ids."
|
"about": "Causes cmap to be created with invalid glyph ids."
|
||||||
},
|
},
|
||||||
|
{ "id": "issue13447-eq",
|
||||||
|
"file": "pdfs/issue13447.pdf",
|
||||||
|
"md5": "a729709950d69ec1cfc516bf559e995d",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
|
{ "id": "issue13447-annotations",
|
||||||
|
"file": "pdfs/issue13447.pdf",
|
||||||
|
"md5": "a729709950d69ec1cfc516bf559e995d",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq",
|
||||||
|
"annotations": true
|
||||||
|
},
|
||||||
{ "id": "bug946506",
|
{ "id": "bug946506",
|
||||||
"file": "pdfs/bug946506.pdf",
|
"file": "pdfs/bug946506.pdf",
|
||||||
"md5": "c28911b5c31bdc337c2ce404c5971cfc",
|
"md5": "c28911b5c31bdc337c2ce404c5971cfc",
|
||||||
|
Loading…
Reference in New Issue
Block a user