summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2020-03-27 14:46:05 -0700
committerMichael Vrhel <michael.vrhel@artifex.com>2020-03-27 14:46:05 -0700
commitd12d2085b5bd08ca1e813d97f3f7f7e630e791a0 (patch)
tree56172749b47c14c26f9f98df58e0f61f1107632f
parent1241ea6848d254de9a9dbcb8c8edf10a59761d1d (diff)
downloadghostpdl-d12d2085b5bd08ca1e813d97f3f7f7e630e791a0.tar.gz
Squashed commit of the opacity_shape branch
This commit removes shape.alpha and opacity.alpha from the graphic state. This involved removal of methods in the postscript based PDF interpreter, changes in the pdf14 device, changes in pdfwrite, the XPS interpreter, and the PS transparency test file that is present in examples and on the cluster. The goal of this commit was to avoid confusion and conflicts between shape.alpha opacity.alpha and the stroke and fill alpha values (CA ca). This change resulted in progressions in the XPS file. There were changes in a couple PDF files that required some investigation. In particular, the change in the dashed lines of Bug694981.pdf. Robin and I looked at this. Robin determined it was due to differences in stroke_add and stroke_fill not giving identical results. In the end, the new output looks closer the what AR provides.
-rw-r--r--Resource/Init/pdf_draw.ps51
-rw-r--r--Resource/Init/pdf_main.ps10
-rw-r--r--Resource/Init/pdf_ops.ps89
-rw-r--r--base/gdevp14.c311
-rw-r--r--base/gdevp14.h2
-rw-r--r--base/gstparam.h2
-rw-r--r--base/gstrans.c44
-rw-r--r--base/gstrans.h18
-rw-r--r--base/gxblend.c8
-rw-r--r--base/gxclimag.c22
-rw-r--r--base/gxclpath.c42
-rw-r--r--base/gxclpath.h6
-rw-r--r--base/gxclrast.c18
-rw-r--r--base/gxgstate.h8
-rw-r--r--devices/vector/gdevpdft.c9
-rw-r--r--examples/transparency_example.ps8
-rw-r--r--psi/ztrans.c57
-rw-r--r--xps/xpscolor.c2
-rw-r--r--xps/xpsgradient.c2
-rw-r--r--xps/xpsimage.c3
-rw-r--r--xps/xpsopacity.c11
-rw-r--r--xps/xpspath.c2
-rw-r--r--xps/xpstile.c4
23 files changed, 347 insertions, 382 deletions
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
index b17f19193..b90ddec05 100644
--- a/Resource/Init/pdf_draw.ps
+++ b/Resource/Init/pdf_draw.ps
@@ -749,7 +749,6 @@ def
/GroupGState .knownget { setgstate } if
newpath //null SMask
- 1 .setopacityalpha 1 .setshapealpha
1 CA 1 ca
/Compatible .setblendmode
% Execute the body of the Form, similar to DoForm.
@@ -1478,7 +1477,7 @@ drawopdict begin
/sh {
OFFlevels length 0 eq {
- setfillstate resolvesh
+ setsmaskstate resolvesh
//sh_save 0 save put
PDFusingtransparency {
gsave
@@ -2292,7 +2291,6 @@ currentdict /last-ditch-bpc-csp undef
PDFfile fileposition exch
gsave //nodict begin
//null .setSMask
- 1 .setopacityalpha 1 .setshapealpha
1 CA 1 ca
/Compatible .setblendmode
DoImage
@@ -2311,11 +2309,10 @@ currentdict /last-ditch-bpc-csp undef
currentdict /SMask get /Matte known {/CS currentdict /ColorSpace get dup pdfopdict /cs get exec } if
>> 0 0 1 1
.begintransparencygroup
- .currentstrokeconstantalpha .currentfillconstantalpha .currentshapealpha .currentopacityalpha 5 -1 roll
+ .currentstrokeconstantalpha .currentfillconstantalpha 3 -1 roll
1 .setfillconstantalpha 1 .setstrokeconstantalpha
- 1 .setopacityalpha 1 .setshapealpha
doimage
- .setopacityalpha .setshapealpha .setfillconstantalpha .setstrokeconstantalpha
+ .setfillconstantalpha .setstrokeconstantalpha
.endtransparencygroup
% tell the compositor we're done with the SMask.
% Note that any SMask in the ExtGState should be reapplied
@@ -2328,10 +2325,10 @@ currentdict /last-ditch-bpc-csp undef
% the image doesn't have an SMask, but the ExtGState does, force a group.
<< /Subtype /Group /Isolated //true >> 0 0 1 1
.begintransparencygroup
- .currentstrokeconstantalpha .currentfillconstantalpha .currentshapealpha .currentopacityalpha 5 -1 roll
- 1 .setopacityalpha 1 .setshapealpha
+ .currentstrokeconstantalpha .currentfillconstantalpha 3 -1 roll
+ 1 .setfillconstantalpha 1 .setstrokeconstantalpha
doimage
- .setopacityalpha .setshapealpha .setfillconstantalpha .setstrokeconstantalpha
+ .setfillconstantalpha .setstrokeconstantalpha
.endtransparencygroup
} {
doimage
@@ -2418,8 +2415,8 @@ currentdict /last-ditch-bpc-csp undef
4 array astore grestore
/image
setup_trans
- { currentdict end setfillstate //true ValidateDecode { imagemask } }
- { ColorSpace setgcolorspace currentdict end setfillblend //false ValidateDecode { image } }
+ { currentdict end setsmaskstate //true ValidateDecode { imagemask } }
+ { ColorSpace setgcolorspace currentdict end setsmaskstate //false ValidateDecode { image } }
ifelse
PDFSTOPONERROR { exec //false } { stopped } ifelse {
dup type /dicttype eq { pop } if % Sometimes image fails to restore the stack
@@ -2856,7 +2853,7 @@ drawopdict begin
( Output may be incorrect.\n) pdfformaterror
currentdict /qTextSaveMatrix get setmatrix
} if
- setfillblend
+ setsmaskstate
PDFfile fileposition exch % pos /Name
% Bug #698226, Acrobat signals an error for recursive XObjects in a PDF file
@@ -3274,7 +3271,7 @@ end
{} 2 index /S knownoget {
/D eq { 2 index /D knownoget not { {3} } if exch pop } if
} if
- 3 index /CA knownoget {.setopacityalpha} if
+ 3 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
3 -1 roll pop
% 2 index annotsetcolor {
0 setdash setlinewidth stroke
@@ -3284,7 +3281,7 @@ end
% If element 3 of the /Border array is 0, then don't draw the border
dup 0 ne {
exch dup length 3 gt { 3 get } { pop {} } ifelse
- 3 index /CA knownoget {.setopacityalpha} if
+ 3 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
% 2 index annotsetcolor {
0 setdash setlinewidth stroke
% } if
@@ -3293,7 +3290,7 @@ end
} ifelse
} ifelse
} {
- 3 index /CA knownoget {.setopacityalpha} if
+ 3 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
1 {}
% 2 index annotsetcolor {
0 setdash setlinewidth stroke
@@ -3305,7 +3302,7 @@ end
/fillborderpath { % <annot> fillborderpath -
gsave
- dup /ca knownoget {.setopacityalpha} if
+ dup /ca knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
annotsetinteriorcolor
{fill} if
grestore
@@ -3782,14 +3779,14 @@ currentdict /set_bc_color undef
annotsetinteriorcolor
{
gsave
- dup /ca knownoget {.setopacityalpha} if
+ dup /ca knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
dup annotrect
5 index /RD knownoget {
applyRD
} if
rectfill
grestore
- dup /CA knownoget {.setopacityalpha} if
+ dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
dup annotsetcolor {
drawborder
} if
@@ -3891,10 +3888,10 @@ currentdict /set_bc_color undef
{
gsave
- dup /ca knownoget {.setopacityalpha} if
+ dup /ca knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
fill
grestore
- dup /CA knownoget {.setopacityalpha} if
+ dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
dup annotsetcolor {
strokeborderpath
} if
@@ -3930,7 +3927,7 @@ currentdict /set_bc_color undef
dup 1 index exch lineto
dup neg lineto
closepath
- 1 index /CA knownoget {.setopacityalpha} if
+ 1 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
1 index fillborderpath
grestore
3 mul
@@ -3956,7 +3953,7 @@ currentdict /set_bc_color undef
2.5 mul dup
0 moveto
0 0 3 -1 roll 0 360 arc
- 1 index /CA knownoget {.setopacityalpha} if
+ 1 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
1 index fillborderpath
grestore
3 mul dup
@@ -3981,7 +3978,7 @@ currentdict /set_bc_color undef
dup 0 exch lineto
0 lineto
closepath
- 1 index /CA knownoget {.setopacityalpha} if
+ 1 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
1 index fillborderpath
grestore
3 mul
@@ -4031,7 +4028,7 @@ currentdict /set_bc_color undef
dup 2 div sub
dup 8.4 mul neg 1 index 5.9 mul neg moveto dup 1.2 div neg 0 lineto
dup 8.4 mul neg exch 5.9 mul lineto closepath
- dup /CA knownoget {.setopacityalpha} if
+ dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
fillborderpath
grestore
} bind executeonly def
@@ -4090,7 +4087,7 @@ currentdict /set_bc_color undef
dup 2 div sub
dup 8.4 mul neg 1 index 5.9 mul neg moveto dup 1.2 div neg 0 lineto
dup 8.4 mul neg exch 5.9 mul lineto closepath
- dup /CA knownoget {.setopacityalpha} if
+ dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if
fillborderpath
grestore
} bind executeonly def
@@ -4554,11 +4551,11 @@ currentdict /set_bc_color undef
dup annotrect rectclip
dup /CA knownoget {
- .setopacityalpha
+ dup .setstrokeconstantalpha .setfillconstantalpha
} if
dup /ca knownoget {
- .setopacityalpha
+ dup .setstrokeconstantalpha .setfillconstantalpha
} if
dup /C knownoget {
diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
index 5cd90556c..2d896b211 100644
--- a/Resource/Init/pdf_main.ps
+++ b/Resource/Init/pdf_main.ps
@@ -3627,20 +3627,20 @@ end % pdfdict
% The following are split out allowing control via ALLOWPSTRANSPARENCY command line param
[
- /.currentblendmode /.currentopacityalpha /.currentshapealpha /.currenttextknockout /.begintransparencytextgroup
+ /.currentblendmode /.currenttextknockout /.begintransparencytextgroup
/.endtransparencytextgroup /.begintransparencymaskgroup /.begintransparencymaskimage /.begintransparencypagegroup
- /.endtransparencymask /.image3x /.abortpdf14devicefilter /.setfillconstantalpha /.setalphaisshape /.currentalphaisshape
+ /.endtransparencymask /.image3x /.abortpdf14devicefilter /.setstrokeconstantalpha /.setfillconstantalpha /.setalphaisshape /.currentalphaisshape
% Used by our own test suite files
%/.pushpdf14devicefilter % transparency-example.ps
%/.poppdf14devicefilter % transparency-example.ps
- %/.setopacityalpha % transparency-example.ps
- %/.setshapealpha % transparency-example.ps
+ %/.setstrokeconstantalpha % transparency-example.ps
+ %/.setfillconstantalpha % transparency-example.ps
%/.endtransparencygroup % transparency-example.ps
% undefining these causes errors/incorrect output
%/.setblendmode /.begintransparencygroup /.settextknockout /.setstrokeoverprint /.setfilloverprint
%/.currentstrokeoverprint /.currentfilloverprint /.currentfillconstantalpha /.currentstrokeconstantalpha
- %/.setstrokeconstantalpha /.setfillconstantalpha /.setSMask /.currentSMask
+ %/.setSMask /.currentSMask
] systemdict dup /ALLOWPSTRANSPARENCY get {pop pop}{.undefinternalnames}ifelse
diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
index 254990c06..df2e3bc6a 100644
--- a/Resource/Init/pdf_ops.ps
+++ b/Resource/Init/pdf_ops.ps
@@ -483,19 +483,19 @@ currentdict /gput_always_allow .undef
% ---------------- Color installation ---------------- %
% Establish a given color (and color space) as current.
-/.settransparencyparams { % <alpha> <smask> .settransparencyparams -
+/.settransparencyparams { % <smask> .settransparencyparams -
PDFusingtransparency {
.currentalphaisshape
{
- 1 .setopacityalpha exch .setshapealpha 1
+ 1
} {
- 1 .setshapealpha exch .setopacityalpha 0
+ 0
} ifelse
% Set the soft mask by rendering the XObject. Doing this every time
% is obviously very inefficient; we'll improve it later.
.settransparencymask
} {
- pop pop
+ pop
} ifelse
} bind executeonly def
/.settransparencymask { % <paramdict> <masknum> .settransparencymask -
@@ -517,16 +517,7 @@ currentdict /gput_always_allow .undef
} ifelse
} ifelse
} bind executeonly def
-% (Non-mask) images must execute setfillblend.
-/setfillblend {
- .currentfillconstantalpha
- .currentSMask .settransparencyparams
-} bind executeonly def
-/setfillstate {
- setfillblend
-} bind executeonly def
-/setstrokestate {
- .currentstrokeconstantalpha
+/setsmaskstate {
.currentSMask .settransparencyparams
} bind executeonly def
/Cdict 15 dict dup begin % <color...> <colorspace> -proc- -
@@ -673,12 +664,12 @@ end def
} ifelse
} bind executeonly def
-/OPsaveDstack 6 dict def % for GroupPushed, saveOP, saveSA, saveBM
+/OPsaveDstack 6 dict def % for GroupPushed, saveOP, saveFillAlpha, saveBM
//OPsaveDstack begin
/GroupPushed //false def
/ChangeBM //false def
- /saveOA 1 def
- /saveSA 1 def
+ /saveStrokeAlpha 1 def
+ /saveFillAlpha 1 def
/saveBM /Normal def
/previous 1 dict def % for nested setup_trans levels
end
@@ -694,7 +685,7 @@ end
/okOPcs mark /DeviceGray 0 /DeviceCMYK 1 /DeviceN 2 /Separation 3 .dicttomark def
% Take care of pushing a transparency group if we need it for SMask or for Overprint..
-% After pushing the group, we save the opacityalpha and shapealpha and change them
+% After pushing the group, we save the ca and CA and change them
% both to 1. For overprint if the colorspace is acceptable, also change to
% CompatibleOverprint if the device needs it.
@@ -721,10 +712,10 @@ end
mark /Subtype /Group /Isolated .currentSMask //null ne .dicttomark
2 index aload pop % pathbbox
.begintransparencygroup
- % After group pushed, set opacityalpha, shapealpha and blendmode
- /saveOA .currentopacityalpha def
- /saveSA .currentshapealpha def
- 1 .setopacityalpha 1 .setshapealpha
+ % After group pushed, set alphas and blendmode
+ /saveStrokeAlpha .currentstrokeconstantalpha def
+ /saveFillAlpha .currentfillconstantalpha def
+ 1 .setfillconstantalpha 1 .setstrokeconstantalpha
/GroupPushed //true def
} {
/GroupPushed //false def
@@ -748,10 +739,10 @@ end
mark /Subtype /Group /Isolated //true .dicttomark
2 index aload pop % pathbbox
.begintransparencygroup
- % After group pushed, set opacityalpha, shapealpha and blendmode
- /saveOA .currentopacityalpha def
- /saveSA .currentshapealpha def
- 1 .setopacityalpha 1 .setshapealpha
+ % After group pushed, set alphas and blendmode
+ /saveStrokeAlpha .currentstrokeconstantalpha def
+ /saveFillAlpha .currentfillconstantalpha def
+ 1 .setfillconstantalpha 1 .setstrokeconstantalpha
/GroupPushed //true def
} {
/GroupPushed //false def
@@ -766,9 +757,9 @@ end
/teardown_trans {
//OPsaveDstack begin
GroupPushed {
- % pop the group, then restore the opacityalpha and shapealpha
+ % pop the group, then restore the alphas
.endtransparencygroup % end the group
- saveOA .setopacityalpha saveSA .setshapealpha
+ saveStrokeAlpha .setstrokeconstantalpha saveFillAlpha .setfillconstantalpha
} if
% Also, if we changed the BM, restore it (AFTER the group was popped)
.currentblendmode /CompatibleOverprint eq {
@@ -904,7 +895,7 @@ currentdict dup /Dpush .undef /Dpop .undef
/S {
OFFlevels length 0 eq {
- setstrokestate .swapcolors /stroke fsexec .swapcolors
+ setsmaskstate .swapcolors /stroke fsexec .swapcolors
} {
newpath
} ifelse
@@ -912,7 +903,7 @@ currentdict dup /Dpush .undef /Dpop .undef
/f {
OFFlevels length 0 eq {
- setfillstate /fill fsexec
+ setsmaskstate /fill fsexec
} {
newpath
} ifelse
@@ -920,7 +911,7 @@ currentdict dup /Dpush .undef /Dpop .undef
/f* {
OFFlevels length 0 eq {
- setfillstate /eofill fsexec
+ setsmaskstate /eofill fsexec
} {
newpath
} ifelse
@@ -932,7 +923,7 @@ currentdict dup /Dpush .undef /Dpop .undef
/B {
OFFlevels length 0 eq {
- setstrokestate setfillstate /.fillstroke fsexec
+ setsmaskstate /.fillstroke fsexec
} {
newpath
} ifelse
@@ -942,7 +933,7 @@ currentdict dup /Dpush .undef /Dpop .undef
/B* {
OFFlevels length 0 eq {
- setstrokestate setfillstate /.eofillstroke fsexec
+ setsmaskstate /.eofillstroke fsexec
} {
newpath
} ifelse
@@ -953,9 +944,9 @@ currentdict dup /Dpush .undef /Dpop .undef
% Clipping:
/Wdict 8 dict dup begin
-/S { OFFlevels length 0 eq { gsave setstrokestate .swapcolors stroke .swapcolors grestore } if n } bind executeonly def
-/f { OFFlevels length 0 eq { gsave setfillstate fill grestore } if n } bind executeonly def
-/f* { OFFlevels length 0 eq { gsave setfillstate eofill grestore } if n } bind executeonly def
+/S { OFFlevels length 0 eq { gsave setsmaskstate .swapcolors stroke .swapcolors grestore } if n } bind executeonly def
+/f { OFFlevels length 0 eq { gsave setsmaskstate fill grestore } if n } bind executeonly def
+/f* { OFFlevels length 0 eq { gsave setsmaskstate eofill grestore } if n } bind executeonly def
/B {
OFFlevels length 0 eq {
.fillstroke
@@ -1471,9 +1462,9 @@ currentdict /clip_if_required .undef
/pdfwrite_textrenderingprocs [
% Tr 0 - Fill
- { setfillstate show } bind executeonly
+ { setsmaskstate show } bind executeonly
% Tr 1 - Stroke
- { currentlinewidth exch setstrokestate
+ { currentlinewidth exch setsmaskstate
% Need to set the stroke width to a value which gives the correct
% width under pdfwrite. Pdfwrite uses (in text mode) an identity
% CTM, so we need to calculate the stroke width which would result
@@ -1493,7 +1484,7 @@ currentdict /clip_if_required .undef
}ifelse setlinewidth
show setlinewidth} bind executeonly
% Tr 2 - Fill then Stroke
- { currentlinewidth exch setstrokestate
+ { currentlinewidth exch setsmaskstate
% Need to set the stroke width to a value which gives the correct
% width under pdfwrite. Pdfwrite uses (in text mode) an identity
% CTM, so we need to calculate the stroke width which would result
@@ -1511,9 +1502,9 @@ currentdict /clip_if_required .undef
% we can ignore it. (wrong answer, but consistent)
pop pop currentlinewidth
}ifelse setlinewidth
- setfillstate show setlinewidth} bind executeonly
+ setsmaskstate show setlinewidth} bind executeonly
% Tr 3 - Neither fill nor stroke
- { setfillstate show } bind executeonly
+ { setsmaskstate show } bind executeonly
%
% pdfwrite emits all text inside a gsave/grestore pair. As
% a result we can't preserve any of the 'clip' modes, as the
@@ -1522,7 +1513,7 @@ currentdict /clip_if_required .undef
%
% Tr 4 - Fill, add to clip
{ gsave 0 .settextrenderingmode
- setfillstate dup show grestore //true charpath } bind executeonly
+ setsmaskstate dup show grestore //true charpath } bind executeonly
% Tr 5 - Stroke, add to clip
{ gsave 1 .settextrenderingmode
currentlinewidth dup
@@ -1534,7 +1525,7 @@ currentdict /clip_if_required .undef
% we can ignore it. (wrong answer, but consistent)
pop pop currentlinewidth
}ifelse setlinewidth
- setstrokestate dup show grestore
+ setsmaskstate dup show grestore
//true charpath} bind executeonly
% Tr 6 - Fill, stroke, add to clip
{ gsave 2 .settextrenderingmode
@@ -1551,7 +1542,7 @@ currentdict /clip_if_required .undef
% we can ignore it. (wrong answer, but consistent)
pop pop currentlinewidth
}ifelse setlinewidth
- setstrokestate setfillstate dup show grestore
+ setsmaskstate dup show grestore
//true charpath} bind executeonly
% Tr 7 - Add to clip
{ //true charpath} bind executeonly
@@ -1567,7 +1558,7 @@ currentdict /clip_if_required .undef
{
.currenttextrenderingmode 1 eq .currenttextrenderingmode 2 eq or
.currenttextrenderingmode 5 eq .currenttextrenderingmode 6 eq or or {
- setstrokestate
+ setsmaskstate
% Need to set the stroke width to a value which gives the correct
% width under pdfwrite. Pdfwrite uses (in text mode) an identity
% CTM, so we need to calculate the stroke width which would result
@@ -1589,7 +1580,7 @@ currentdict /clip_if_required .undef
% conditionally set fillstate to avoid multiple operations during text operators
/settextfillstate {
- TextFillStateNeeded { setfillstate //false /TextFillStateNeeded gput } if
+ TextFillStateNeeded { setsmaskstate //false /TextFillStateNeeded gput } if
} bind executeonly def
% If current path is not known to be valid, use the clip path
@@ -1786,7 +1777,7 @@ currentdict /clip_if_required .undef
% correctly.
gsave .currenttextrenderingmode 4 sub .settextrenderingmode
setstrokeforTrpreservation
- setstrokestate settextfillstate //false TextTransSetup dup show grestore TextTransTeardown } if
+ setsmaskstate settextfillstate //false TextTransSetup dup show grestore TextTransTeardown } if
//false charpath
3 copy 32 eq { add } { exch pop } ifelse
% Stack: str wthis xorig yorig wword wchar ccode wextra
@@ -1873,7 +1864,7 @@ currentdict /clip_if_required .undef
}
{
.currentPDFfontsize 0 eq not {
- setstrokestate //true TextTransSetup
+ setsmaskstate //true TextTransSetup
currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix
currentdict /qTextSaveMatrix known {qTextSaveMatrix setmatrix} if
.swapcolors stroke TextTransTeardown .swapcolors
@@ -1893,7 +1884,7 @@ currentdict /clip_if_required .undef
{
% Don't try to draw text when the point size is 0
.currentPDFfontsize 0 eq not {
- setstrokestate settextfillstate
+ setsmaskstate settextfillstate
% While text will always have a currentpoint, strokepath seems to mess with it.
% we get the currentpoint, then use moveto to restore it.
currentpoint
diff --git a/base/gdevp14.c b/base/gdevp14.c
index 2d11caeae..1dcdcec31 100644
--- a/base/gdevp14.c
+++ b/base/gdevp14.c
@@ -1335,7 +1335,7 @@ pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
static int
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
- bool knockout, uint16_t alpha, uint16_t shape,
+ bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
gs_blend_mode_t blend_mode, bool idle, uint mask_id,
int numcomps, bool cm_back_drop,
cmm_profile_t *group_profile,
@@ -1378,6 +1378,7 @@ pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
buf->knockout = knockout;
buf->alpha = alpha;
buf->shape = shape;
+ buf->opacity = opacity;
buf->blend_mode = blend_mode;
buf->mask_id = mask_id;
buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
@@ -2920,9 +2921,22 @@ pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
{
pdf14_device * pdev = (pdf14_device *)dev;
- pdev->opacity = pgs->opacity.alpha;
- pdev->shape = pgs->shape.alpha;
- pdev->alpha = pgs->opacity.alpha * pgs->shape.alpha;
+ if (pgs->alphaisshape) {
+ pdev->opacity = 1.0;
+ if (pgs->is_fill_color) {
+ pdev->shape = pgs->fillconstantalpha;
+ } else {
+ pdev->shape = pgs->strokeconstantalpha;
+ }
+ } else {
+ pdev->shape = 1.0;
+ if (pgs->is_fill_color) {
+ pdev->opacity = pgs->fillconstantalpha;
+ } else {
+ pdev->opacity = pgs->strokeconstantalpha;
+ }
+ }
+ pdev->alpha = pdev->opacity * pdev->shape;
pdev->blend_mode = pgs->blend_mode;
pdev->overprint = pgs->overprint;
pdev->stroke_overprint = pgs->stroke_overprint;
@@ -2959,8 +2973,8 @@ update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
/* The only idempotent blend modes are Normal, Darken and Lighten */
if ((pgs->alpha != 0xFFFF) ||
(pgs->blend_mode != BLEND_MODE_Normal && pgs->blend_mode != BLEND_MODE_Darken && pgs->blend_mode != BLEND_MODE_Lighten) ||
- (pgs->opacity.alpha != 1.0) ||
- (pgs->shape.alpha != 1.0) ||
+ (pgs->fillconstantalpha != 1.0) ||
+ (pgs->strokeconstantalpha != 1.0) ||
(hastrans))
{
/*
@@ -2997,6 +3011,8 @@ push_shfill_group(pdf14_clist_device *pdev,
params.Isolated = false;
params.Knockout = true;
+ params.group_opacity = fudged_pgs.fillconstantalpha;
+ params.group_shape = 1.0;
code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
/* We have the group handle the blendmode and the opacity,
@@ -3007,7 +3023,8 @@ push_shfill_group(pdf14_clist_device *pdev,
* the fill operation as part of doing the stroking, we don't
* push another one. */
gs_setblendmode(pgs, BLEND_MODE_Normal);
- gs_setopacityalpha(pgs, 1.0);
+ gs_setfillconstantalpha(pgs, 1.0);
+ gs_setstrokeconstantalpha(pgs, 1.0);
if (pdev) {
code = pdf14_clist_update_params(pdev, pgs, false, NULL);
if (code < 0)
@@ -3094,7 +3111,7 @@ pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
/* Non-idempotent blends require a transparency
* group to be pushed because shadings might
* paint several pixels twice. */
- push_group = gs_currentopacityalpha(pgs) != 1.0 ||
+ push_group = pgs->fillconstantalpha != 1.0 ||
!blend_is_idempotent(gs_currentblendmode(pgs));
pinst =
(gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
@@ -3122,6 +3139,7 @@ pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
if (box.q.y > path_box.q.y)
box.q.y = path_box.q.y;
}
+ /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
code = push_shfill_group(NULL, &new_pgs, &box);
} else
update_lop_for_pdf14(&new_pgs, pdcolor);
@@ -3164,7 +3182,7 @@ pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
/* Non-idempotent blends require a transparency
* group to be pushed because shadings might
* paint several pixels twice. */
- push_group = gs_currentopacityalpha(pgs) != 1.0 ||
+ push_group = pgs->strokeconstantalpha != 1.0 ||
!blend_is_idempotent(gs_currentblendmode(pgs));
}
if (push_group) {
@@ -3213,6 +3231,8 @@ pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
if (box.q.y > path_box.q.y)
box.q.y = path_box.q.y;
}
+ /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
+ new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
code = push_shfill_group(NULL, &new_pgs, &box);
} else
update_lop_for_pdf14(&new_pgs, pdcolor);
@@ -3243,12 +3263,13 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
gs_transparency_group_params_t params = { 0 };
gs_fixed_rect clip_bbox;
gs_rect bbox, group_stroke_box;
- float opacity;
- gs_blend_mode_t blend_mode;
gs_fixed_rect path_bbox;
int expansion_code;
gs_fixed_point expansion;
pdf14_device *p14dev = (pdf14_device *)dev;
+ float stroke_alpha = cpgs->strokeconstantalpha;
+ float fill_alpha = cpgs->fillconstantalpha;
+ gs_blend_mode_t blend_mode = cpgs->blend_mode;
/* Break const just once, neatly */
const_breaker.cpgs = cpgs;
@@ -3258,9 +3279,6 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
(pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
return 0;
- opacity = pgs->opacity.alpha;
- blend_mode = pgs->blend_mode;
-
code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
if (code < 0 && code != gs_error_unknownerror)
return code;
@@ -3297,7 +3315,7 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
return code;
/* See if overprint is enabled for both stroke and fill AND if ca == CA */
- if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
+ if (fill_alpha == stroke_alpha &&
p14dev->overprint && p14dev->stroke_overprint &&
dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
/* Push a non-isolated non-knockout group with alpha = 1.0 and
@@ -3306,6 +3324,8 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
params.Isolated = false;
params.group_color = UNKNOWN;
params.Knockout = false;
+ params.group_opacity = 1.0;
+ params.group_shape = fill_alpha;
/* non-isolated non-knockout group pushed with original alpha and blend mode */
code = pdf14_begin_transparency_group(dev, &params,
@@ -3313,25 +3333,22 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
if (code < 0)
return code;
- /* Change alpha to 1.0 and blend mode to compatible overprint for actual drawing */
- (void)gs_setopacityalpha(pgs, 1.0); /* Can never fail */
+ /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
+ (void)gs_setfillconstantalpha(pgs, 1.0);
(void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
- if (pgs->fillconstantalpha > 0) {
- p14dev->op_state = PDF14_OP_STATE_FILL;
- code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
- if (code < 0)
- goto cleanup;
- }
+ p14dev->op_state = PDF14_OP_STATE_FILL;
+ code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
+ if (code < 0)
+ goto cleanup;
- if (pgs->strokeconstantalpha > 0) {
- gs_swapcolors_quick(pgs); /* flips stroke_color_index (to stroke) */
- p14dev->op_state = PDF14_OP_STATE_STROKE;
- code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
- gs_swapcolors_quick(pgs); /* this flips pgs->stroke_color_index back as well */
- if (code < 0)
- goto cleanup; /* bail out (with colors swapped back to fill) */
- }
+ (void)gs_setstrokeconstantalpha(pgs, 1.0);
+ gs_swapcolors_quick(pgs); /* flips stroke_color_index (to stroke) */
+ p14dev->op_state = PDF14_OP_STATE_STROKE;
+ code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
+ gs_swapcolors_quick(pgs); /* this flips pgs->stroke_color_index back as well */
+ if (code < 0)
+ goto cleanup; /* bail out (with colors swapped back to fill) */
} else {
/* Push a non-isolated knockout group. Do not change the alpha or
@@ -3339,35 +3356,31 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
params.Isolated = false;
params.group_color = UNKNOWN;
params.Knockout = true;
+ params.group_shape = 1.0;
+ params.group_opacity = 1.0;
/* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
- (void)gs_setopacityalpha(pgs, 1.0); /* Can never fail */
(void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
+ code = pdf14_begin_transparency_group(dev, &params, &group_stroke_box,
+ pgs, dev->memory);
- code = pdf14_begin_transparency_group(dev, &params,
- &group_stroke_box, pgs, dev->memory);
/* restore blend mode for actual drawing in the group */
(void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
- if (code < 0) {
- /* Make sure we put everything back even if we exit with an error. */
- (void)gs_setopacityalpha(pgs, opacity);
- return code;
- }
-
- (void)gs_setopacityalpha(pgs, pgs->fillconstantalpha); /* Can never fail */
p14dev->op_state = PDF14_OP_STATE_FILL;
/* If we are in an overprint situation, set the blend mode to compatible
overprint */
if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
- gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
+ (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
- gs_setblendmode(pgs, blend_mode); /* Can never fail */
+ (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
if (code < 0)
goto cleanup;
- gs_setopacityalpha(pgs, pgs->strokeconstantalpha); /* Can never fail */
+ /* Note that the stroke can end up doing fill methods */
+ (void)gs_setfillconstantalpha(pgs, stroke_alpha);
+
gs_swapcolors_quick(pgs);
p14dev->op_state = PDF14_OP_STATE_STROKE;
if (pgs->stroke_overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
@@ -3380,23 +3393,17 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
}
cleanup:
- /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
- (void)gs_setopacityalpha(pgs, 1.0); /* Can never fail */
- (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
+ /* Restore the state */
+ (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
+ (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
+ (void)gs_setfillconstantalpha(pgs, fill_alpha);
- /* Restore where we were. If an error occured while in the group push
- return that error code but try to do the cleanup */
code2 = pdf14_end_transparency_group(dev, pgs);
if (code2 < 0) {
/* At this point things have gone very wrong. We should just shut down */
code = gs_abort_pdf14trans_device(pgs);
return code2;
}
-
- /* Restore if there were any changes */
- (void)gs_setopacityalpha(pgs, opacity); /* Can never fail */
- (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
-
return code;
}
@@ -3869,7 +3876,7 @@ pdf14_fill_mask(gx_device * orig_dev,
group_rect.q.y = y + h;
if (!(w <= 0 || h <= 0)) {
code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
- 1, 0, 65535, 65535, ptile->blending_mode, 0, 0,
+ 1, 0, 65535, 65535, 65535, ptile->blending_mode, 0, 0,
ptile->ttrans->n_chan-1, false, NULL, NULL, NULL, NULL);
if (code < 0)
return code;
@@ -4021,7 +4028,7 @@ pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
blend_mode = ptile->blending_mode;
memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
- (uint16_t)floor(65535 * p14dev->shape + 0.5),
+ (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
blend_mode, 0, 0, n_chan_tile-1,
false, NULL, NULL, pgs_noconst,
pdev);
@@ -4264,7 +4271,7 @@ pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
"[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
ptile->uid.id, ptile->id);
code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
- pgs->blend_mode, 0, 0,
+ 65535, pgs->blend_mode, 0, 0,
ptile->ttrans->n_chan-1, false, NULL,
NULL, (gs_gstate *)pgs, dev);
/* Set up the output buffer information now that we have
@@ -4335,10 +4342,8 @@ pdf14_set_params(gs_gstate * pgs,
pgs->blend_mode = pparams->blend_mode;
if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
pgs->text_knockout = pparams->text_knockout;
- if (pparams->changed & PDF14_SET_SHAPE_ALPHA)
- pgs->shape.alpha = pparams->shape.alpha;
- if (pparams->changed & PDF14_SET_OPACITY_ALPHA)
- pgs->opacity.alpha = pparams->opacity.alpha;
+ if (pparams->changed & PDF14_SET_AIS)
+ pgs->alphaisshape = pparams->ais;
if (pparams->changed & PDF14_SET_OVERPRINT)
pgs->overprint = pparams->overprint;
if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
@@ -4349,6 +4354,10 @@ pdf14_set_params(gs_gstate * pgs,
pgs->strokeconstantalpha = pparams->strokeconstantalpha;
if (pparams->changed & PDF_SET_FILLSTROKE_STATE) {
gs_swapcolors_quick(pgs);
+ if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
+ pgs->is_fill_color = false;
+ else
+ pgs->is_fill_color = true;
}
pdf14_set_marking_params(dev, pgs);
}
@@ -4969,32 +4978,41 @@ pdf14_create_compositor(gx_device * dev, gx_device * * pcdev,
static int
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
gs_blend_mode_t blend_mode, float opacity,
- bool is_clist)
+ float shape, bool is_clist)
{
int code;
gs_transparency_group_params_t params = { 0 };
gs_rect bbox = { 0 }; /* Bounding box is set by parent */
pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
+ float alpha = pgs->fillconstantalpha;
/* Push a non-isolated knock-out group making sure the opacity and blend
mode are correct */
params.Isolated = false;
params.Knockout = true;
params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
- gs_setopacityalpha(pgs, 1.0);
+ params.group_opacity = 1.0;
+ params.group_shape = 1.0;
+
+ gs_setfillconstantalpha(pgs, 1.0);
gs_setblendmode(pgs, BLEND_MODE_Normal);
+
if (is_clist) {
code = pdf14_clist_update_params(pdev, pgs, false, NULL);
if (code < 0)
return code;
}
+
code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
if (code < 0)
return code;
- gs_setopacityalpha(pgs, opacity);
+
+ gs_setfillconstantalpha(pgs, alpha);
gs_setblendmode(pgs, blend_mode);
- if (is_clist)
+
+ if (is_clist) {
code = pdf14_clist_update_params(pdev, pgs, false, NULL);
+ }
return code;
}
@@ -5008,10 +5026,14 @@ pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
int code;
gs_text_enum_t *penum;
gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
- float opacity = gs_currentopacityalpha(pgs);
+ float opacity = pgs->fillconstantalpha;
+ float shape = 1.0;
bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
pdf14_device *pdev = (pdf14_device*)dev;
bool draw = !(text->operation & TEXT_DO_NONE);
+ uint text_mode = gs_currenttextrenderingmode(pgs);
+ bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
+ bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
if_debug0m('v', memory, "[v]pdf14_text_begin\n");
pdf14_set_marking_params(dev, pgs);
@@ -5044,11 +5066,13 @@ pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
}
- if (gs_currenttextknockout(pgs) && (blend_issue || opacity != 1.0) &&
- gs_currenttextrenderingmode(pgs) != 3 && /* don't bother with invisible text */
- pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
+ if (gs_currenttextknockout(pgs) && (blend_issue ||
+ (pgs->fillconstantalpha != 1.0 && text_fill) ||
+ (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
+ text_mode != 3 && /* don't bother with invisible text */
+ pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
if (draw) {
- code = pdf14_push_text_group(dev, pgs, blend_mode, opacity,
+ code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
false);
}
*ppenum = (gs_text_enum_t *)penum;
@@ -5284,7 +5308,7 @@ pdf14_begin_transparency_group(gx_device *dev,
gs_gstate *pgs, gs_memory_t *mem)
{
pdf14_device *pdev = (pdf14_device *)dev;
- double alpha = pgs->opacity.alpha * pgs->shape.alpha;
+ double alpha = ptgp->group_opacity * ptgp->group_shape;
gs_int_rect rect;
int code;
bool isolated = ptgp->Isolated;
@@ -5353,9 +5377,10 @@ pdf14_begin_transparency_group(gx_device *dev,
if (code < 0)
return code;
code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
- (uint16_t)floor (65535 * alpha + 0.5),
- (uint16_t)floor (65535 * pgs->shape.alpha + 0.5),
- pgs->blend_mode, ptgp->idle,
+ (uint16_t)floor (65535 * alpha + 0.5),
+ (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
+ (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
+ pgs->blend_mode, ptgp->idle,
ptgp->mask_id, pdev->color_info.num_components,
cm_back_drop, group_profile, tos_profile,
pgs, dev);
@@ -7102,6 +7127,13 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
p14dev->pad = target->pad;
p14dev->log2_align_mod = target->log2_align_mod;
p14dev->is_planar = target->is_planar;
+
+ p14dev->alpha = 1.0;
+ p14dev->shape = 1.0;
+ p14dev->opacity = 1.0;
+ p14dev->fillconstantalpha = 1.0;
+ p14dev->strokeconstantalpha = 1.0;
+
/* If the target profile was CIELAB (and we are not using a blend CS),
then overide with default RGB for
proper blending. During put_image we will convert from RGB to
@@ -7396,8 +7428,8 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
*pbuf++ = pparams->blend_mode;
*pbuf++ = pparams->group_color;
put_value(pbuf, pparams->group_color_numcomps);
- put_value(pbuf, pparams->opacity.alpha);
- put_value(pbuf, pparams->shape.alpha);
+ put_value(pbuf, pparams->opacity);
+ put_value(pbuf, pparams->shape);
put_value(pbuf, pparams->bbox);
put_value(pbuf, pparams->text_group);
mask_id = pparams->mask_id;
@@ -7480,8 +7512,8 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
pdf14_needed = cdev->page_pdf14_needed;
break;
case PDF14_SET_BLEND_PARAMS:
- if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity.alpha != 1.0 ||
- pparams->shape.alpha != 1.0)
+ if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
+ pparams->shape != 1.0)
pdf14_needed = true; /* the compositor will be needed while reading */
else if (smask_level == 0 && trans_group_level == 0)
pdf14_needed = false; /* At page level, set back to false */
@@ -7493,10 +7525,8 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
*pbuf++ = pparams->blend_mode;
if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
*pbuf++ = pparams->text_knockout;
- if (pparams->changed & PDF14_SET_OPACITY_ALPHA)
- put_value(pbuf, pparams->opacity.alpha);
- if (pparams->changed & PDF14_SET_SHAPE_ALPHA)
- put_value(pbuf, pparams->shape.alpha);
+ if (pparams->changed & PDF14_SET_AIS)
+ put_value(pbuf, pparams->ais);
if (pparams->changed & PDF14_SET_OVERPRINT)
put_value(pbuf, pparams->overprint);
if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
@@ -7618,8 +7648,8 @@ c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
params.blend_mode = *data++;
params.group_color = *data++; /* Trans group color */
read_value(data,params.group_color_numcomps); /* color group size */
- read_value(data, params.opacity.alpha);
- read_value(data, params.shape.alpha);
+ read_value(data, params.opacity);
+ read_value(data, params.shape);
read_value(data, params.bbox);
read_value(data, params.text_group);
read_value(data, params.mask_id);
@@ -7696,10 +7726,8 @@ c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
params.blend_mode = *data++;
if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
params.text_knockout = *data++;
- if (params.changed & PDF14_SET_OPACITY_ALPHA)
- read_value(data, params.opacity.alpha);
- if (params.changed & PDF14_SET_SHAPE_ALPHA)
- read_value(data, params.shape.alpha);
+ if (params.changed & PDF14_SET_AIS)
+ read_value(data, params.ais);
if (params.changed & PDF14_SET_OVERPRINT)
read_value(data, params.overprint);
if (params.changed & PDF14_SET_STROKEOVERPRINT)
@@ -9123,13 +9151,9 @@ pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
changed |= PDF14_SET_TEXT_KNOCKOUT;
params.text_knockout = pdev->text_knockout = pgs->text_knockout;
}
- if (pgs->shape.alpha != pdev->shape) {
- changed |= PDF14_SET_SHAPE_ALPHA;
- params.shape.alpha = pdev->shape = pgs->shape.alpha;
- }
- if (pgs->opacity.alpha != pdev->opacity) {
- changed |= PDF14_SET_OPACITY_ALPHA;
- params.opacity.alpha = pdev->opacity = pgs->opacity.alpha;
+ if (pgs->alphaisshape != pdev->ais) {
+ changed |= PDF14_SET_AIS;
+ params.ais = pdev->shape = pgs->alphaisshape;
}
if (pgs->overprint != pdev->overprint) {
changed |= PDF14_SET_OVERPRINT;
@@ -9147,9 +9171,13 @@ pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
changed |= PDF14_SET_STROKECONSTANTALPHA;
params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
}
- if (pgs->is_fill_color != pdev->op_state) {
+ if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
changed |= PDF_SET_FILLSTROKE_STATE;
- params.op_fs_state = pdev->op_state = pgs->is_fill_color;
+ params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
+ }
+ if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
+ changed |= PDF_SET_FILLSTROKE_STATE;
+ params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
}
if (crop_blend_params) {
params.ctm = group_params->ctm;
@@ -9224,7 +9252,7 @@ pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
/* Non-idempotent blends require a transparency
* group to be pushed because shadings might
* paint several pixels twice. */
- push_group = gs_currentopacityalpha(pgs) != 1.0 ||
+ push_group = pgs->fillconstantalpha != 1.0 ||
!blend_is_idempotent(gs_currentblendmode(pgs));
pinst =
(gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
@@ -9252,6 +9280,7 @@ pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
if (box.q.y > path_box.q.y)
box.q.y = path_box.q.y;
}
+ /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
code = push_shfill_group(pdev, &new_pgs, &box);
} else
update_lop_for_pdf14(&new_pgs, pdcolor);
@@ -9306,7 +9335,7 @@ pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
/* Non-idempotent blends require a transparency
* group to be pushed because shadings might
* paint several pixels twice. */
- push_group = gs_currentopacityalpha(pgs) != 1.0 ||
+ push_group = pgs->strokeconstantalpha != 1.0 ||
!blend_is_idempotent(gs_currentblendmode(pgs));
if (pdev->trans_group_parent_cmap_procs != NULL) {
pinst =
@@ -9358,6 +9387,8 @@ pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
if (box.q.y > path_box.q.y)
box.q.y = path_box.q.y;
}
+ /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
+ new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
code = push_shfill_group(pdev, &new_pgs, &box);
} else
update_lop_for_pdf14(&new_pgs, pdcolor);
@@ -9397,7 +9428,8 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs
gs_transparency_group_params_t params = { 0 };
gs_fixed_rect clip_bbox;
gs_rect bbox, group_stroke_box;
- float opacity;
+ float fill_alpha;
+ float stroke_alpha;
gs_blend_mode_t blend_mode;
gs_fixed_rect path_bbox;
int expansion_code;
@@ -9407,7 +9439,8 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs
const_breaker.cpgs = cpgs;
pgs = const_breaker.pgs;
- opacity = pgs->opacity.alpha;
+ fill_alpha = pgs->fillconstantalpha;
+ stroke_alpha = pgs->strokeconstantalpha;
blend_mode = pgs->blend_mode;
code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
@@ -9449,35 +9482,30 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs
if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
pgs->overprint && pgs->stroke_overprint &&
dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
- /* Push a non-isolated non-knockout group with alpha = 1.0 and
- compatible overprint mode. Group will be composited with
- original alpha and blend mode */
+
params.Isolated = false;
params.group_color = UNKNOWN;
params.Knockout = false;
+ params.group_opacity = fill_alpha;
+ params.group_shape = 1.0;
/* non-isolated non-knockout group pushed with original alpha and blend mode */
code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
if (code < 0)
return code;
- /* Change alpha to 1.0 and blend mode to compatible overprint for actual drawing */
- (void)gs_setopacityalpha(pgs, 1.0); /* Can never fail */
+ /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
+ (void)gs_setfillconstantalpha(pgs, 1.0);
+ (void)gs_setstrokeconstantalpha(pgs, 1.0);
(void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
- /* Do fill */
- if (pgs->fillconstantalpha > 0.0) {
- code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
- if (code < 0)
- goto cleanup;
- }
+ code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
+ if (code < 0)
+ goto cleanup;
- /* Do stroke */
- if (pgs->strokeconstantalpha > 0.0) {
- code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
- if (code < 0)
- goto cleanup;
- }
+ code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
+ if (code < 0)
+ goto cleanup;
} else {
/* Push a non-isolated knockout group. Do not change the alpha or
@@ -9485,21 +9513,19 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs
params.Isolated = false;
params.group_color = UNKNOWN;
params.Knockout = true;
+ params.group_opacity = 1.0;
+ params.group_shape = 1.0;
/* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
- (void)gs_setopacityalpha(pgs, 1.0); /* Can never fail */
+ (void)gs_setfillconstantalpha(pgs, 1.0);
(void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
-
code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
+
/* restore blend mode for actual drawing in the group */
(void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
- if (code < 0) {
- (void)gs_setopacityalpha(pgs, opacity); /* Can never fail */
- return code;
- }
- if (pgs->fillconstantalpha > 0.0) {
- (void)gs_setopacityalpha(pgs, pgs->fillconstantalpha); /* Can never fail */
+ if (fill_alpha > 0.0) {
+ (void)gs_setfillconstantalpha(pgs, fill_alpha);
/* If we are in an overprint situation, set the blend mode to compatible
overprint */
@@ -9514,20 +9540,27 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs
(void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
}
- if (pgs->strokeconstantalpha > 0.0) {
- (void)gs_setopacityalpha(pgs, pgs->strokeconstantalpha); /* Can never fail */
- if (pgs->stroke_overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
+ if (stroke_alpha > 0.0) {
+ /* Note that the stroke can end up looking like a fill here */
+ (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
+ (void)gs_setfillconstantalpha(pgs, stroke_alpha);
+
+ if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
(void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
if (code < 0)
goto cleanup;
+
+ if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
+ (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
}
}
cleanup:
/* Now during the pop do the compositing with alpha of 1.0 and normal blend */
- (void)gs_setopacityalpha(pgs, 1.0); /* Can never fail */
+ (void)gs_setfillconstantalpha(pgs, 1.0);
+ (void)gs_setstrokeconstantalpha(pgs, 1.0);
(void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
/* Restore where we were. If an error occured while in the group push
@@ -9540,7 +9573,8 @@ cleanup:
}
/* Restore if there were any changes */
- (void)gs_setopacityalpha(pgs, opacity); /* Can never fail */
+ (void)gs_setfillconstantalpha(pgs, fill_alpha);
+ (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
(void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
return code;
@@ -9608,9 +9642,13 @@ pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
gs_text_enum_t *penum;
int code;
gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
- float opacity = gs_currentopacityalpha(pgs);
+ float opacity = pgs->fillconstantalpha;
+ float shape = 1.0;
bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
bool draw = !(text->operation & TEXT_DO_NONE);
+ uint text_mode = gs_currenttextrenderingmode(pgs);
+ bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
+ bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
if_debug0m('v', memory, "[v]pdf14_clist_text_begin\n");
/*
@@ -9648,11 +9686,14 @@ pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
3) Text knockout is set to true
4) And we are actually drawing text
*/
- if (gs_currenttextknockout(pgs) && (blend_issue || opacity != 1.0) &&
- gs_currenttextrenderingmode(pgs) != 3 && /* don't bother with invisible text */
+
+ if (gs_currenttextknockout(pgs) && (blend_issue ||
+ (pgs->fillconstantalpha != 1.0 && text_fill) ||
+ (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
+ text_mode != 3 && /* don't bother with invisible text */
pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
if (draw) {
- code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, true);
+ code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
if (code == 0)
pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED; /* Needed during clist writing */
}
diff --git a/base/gdevp14.h b/base/gdevp14.h
index e4d4dfaae..ef1fd6b58 100644
--- a/base/gdevp14.h
+++ b/base/gdevp14.h
@@ -137,6 +137,7 @@ struct pdf14_buf_s {
bool isolated;
bool knockout;
uint16_t alpha;
+ uint16_t opacity;
uint16_t shape;
gs_blend_mode_t blend_mode;
int num_spots; /* helpful when going between Gray+spots, RGB+spots, CMYK+spots */
@@ -208,6 +209,7 @@ typedef struct pdf14_device_s {
pdf14_ctx *ctx;
pdf14_smaskcolor_t *smaskcolor;
+ bool ais;
float opacity;
float shape;
float alpha; /* alpha = opacity * shape */
diff --git a/base/gstparam.h b/base/gstparam.h
index e8aa4fb36..606cdea0a 100644
--- a/base/gstparam.h
+++ b/base/gstparam.h
@@ -72,6 +72,8 @@ typedef struct gs_transparency_group_params_s {
const gs_color_space *ColorSpace;
bool Isolated;
bool Knockout;
+ float group_shape;
+ float group_opacity;
bool image_with_SMask;
int text_group;
bool idle;
diff --git a/base/gstrans.c b/base/gstrans.c
index bf515c285..0f962ab7f 100644
--- a/base/gstrans.c
+++ b/base/gstrans.c
@@ -65,34 +65,6 @@ gs_currentblendmode(const gs_gstate *pgs)
}
int
-gs_setopacityalpha(gs_gstate *pgs, double alpha)
-{
- if_debug2m('v', pgs->memory, "[v]("PRI_INTPTR")opacity.alpha = %g\n", (intptr_t)pgs, alpha);
- pgs->opacity.alpha = (alpha < 0.0 ? 0.0 : alpha > 1.0 ? 1.0 : alpha);
- return 0;
-}
-
-float
-gs_currentopacityalpha(const gs_gstate *pgs)
-{
- return pgs->opacity.alpha;
-}
-
-int
-gs_setshapealpha(gs_gstate *pgs, double alpha)
-{
- if_debug2m('v', pgs->memory, "[v]("PRI_INTPTR")shape.alpha = %g\n", (intptr_t)pgs, alpha);
- pgs->shape.alpha = (alpha < 0.0 ? 0.0 : alpha > 1.0 ? 1.0 : alpha);
- return 0;
-}
-
-float
-gs_currentshapealpha(const gs_gstate *pgs)
-{
- return pgs->shape.alpha;
-}
-
-int
gs_settextknockout(gs_gstate *pgs, bool knockout)
{
if_debug2m('v', pgs->memory, "[v]("PRI_INTPTR")text_knockout = %s\n",
@@ -193,7 +165,7 @@ gs_gstate_update_pdf14trans(gs_gstate * pgs, gs_pdf14trans_params_t * pparams)
}
void
-gs_trans_group_params_init(gs_transparency_group_params_t *ptgp)
+gs_trans_group_params_init(gs_transparency_group_params_t *ptgp, float opacity)
{
ptgp->ColorSpace = NULL; /* bogus, but can't do better */
ptgp->Isolated = false;
@@ -202,6 +174,8 @@ gs_trans_group_params_init(gs_transparency_group_params_t *ptgp)
ptgp->image_with_SMask = false;
ptgp->mask_id = 0;
ptgp->iccprofile = NULL;
+ ptgp->group_opacity = opacity;
+ ptgp->group_shape = 1.0;
}
int
@@ -236,10 +210,11 @@ gs_begin_transparency_group(gs_gstate *pgs,
params.Isolated = ptgp->Isolated;
params.Knockout = ptgp->Knockout;
params.image_with_SMask = ptgp->image_with_SMask;
- params.opacity = pgs->opacity;
- params.shape = pgs->shape;
+ params.opacity = ptgp->group_opacity;
+ params.shape = ptgp->group_shape;
params.blend_mode = pgs->blend_mode;
params.text_group = ptgp->text_group;
+
/* This function is called during the c-list writer side.
Store some information so that we know what the color space is
so that we can adjust according later during the clist reader.
@@ -361,8 +336,9 @@ gx_begin_transparency_group(gs_gstate * pgs, gx_device * pdev,
tgp.iccprofile = pparams->iccprofile;
tgp.icc_hashcode = pparams->icc_hash;
- pgs->opacity.alpha = pparams->opacity.alpha;
- pgs->shape.alpha = pparams->shape.alpha;
+ tgp.group_opacity = pparams->opacity;
+ tgp.group_shape = pparams->shape;
+
pgs->blend_mode = pparams->blend_mode;
bbox = pparams->bbox;
#ifdef DEBUG
@@ -373,6 +349,7 @@ gx_begin_transparency_group(gs_gstate * pgs, gx_device * pdev,
dmlprintf6(pdev->memory, "[v]("PRI_INTPTR")gx_begin_transparency_group [%g %g %g %g] Num_grp_clr_comp = %d\n",
(intptr_t)pgs, bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y,
pparams->group_color_numcomps);
+ dmlprintf2(pdev->memory, " opacity = %g shape = %g\n", pparams->opacity, pparams->shape);
if (tgp.ColorSpace)
dmprintf1(pdev->memory, " CS = %s",
cs_names[(int)gs_color_space_get_index(tgp.ColorSpace)]);
@@ -382,6 +359,7 @@ gx_begin_transparency_group(gs_gstate * pgs, gx_device * pdev,
tgp.Isolated, tgp.Knockout);
if (tgp.iccprofile)
dmprintf(pdev->memory, " Have ICC Profile for blending\n");
+
}
#endif
return (*dev_proc(pdev, begin_transparency_group)) (pdev, &tgp, &bbox, pgs,
diff --git a/base/gstrans.h b/base/gstrans.h
index 3dc729833..b08bbb81d 100644
--- a/base/gstrans.h
+++ b/base/gstrans.h
@@ -69,8 +69,7 @@ typedef enum {
/* Bit definitions for serializing PDF 1.4 parameters */
#define PDF14_SET_BLEND_MODE (1 << 0)
#define PDF14_SET_TEXT_KNOCKOUT (1 << 1)
-#define PDF14_SET_SHAPE_ALPHA (1 << 2)
-#define PDF14_SET_OPACITY_ALPHA (1 << 3)
+#define PDF14_SET_AIS (1 << 2)
#define PDF14_SET_OVERPRINT (1 << 4)
#define PDF14_SET_FILLCONSTANTALPHA (1 << 6)
#define PDF14_SET_STROKECONSTANTALPHA (1 << 7)
@@ -88,10 +87,6 @@ typedef enum {
PDF14_TEXTGROUP_MISSING_ET /* We pushed a group already and then had another BT occur */
} pdf14_text_group_state;
-typedef struct gs_transparency_source_s {
- float alpha; /* constant alpha */
-} gs_transparency_source_t;
-
struct gs_pdf14trans_params_s {
/* The type of trasnparency operation */
pdf14_compositor_operations pdf14_op;
@@ -124,8 +119,9 @@ struct gs_pdf14trans_params_s {
gs_blend_mode_t blend_mode;
bool text_knockout;
int text_group;
- gs_transparency_source_t opacity;
- gs_transparency_source_t shape;
+ bool ais;
+ float opacity;
+ float shape;
float fillconstantalpha;
float strokeconstantalpha;
bool mask_is_image;
@@ -160,10 +156,6 @@ typedef struct gs_pdf14trans_s {
/* Access transparency-related graphics state elements. */
int gs_setblendmode(gs_gstate *, gs_blend_mode_t);
gs_blend_mode_t gs_currentblendmode(const gs_gstate *);
-int gs_setopacityalpha(gs_gstate *, double);
-float gs_currentopacityalpha(const gs_gstate *);
-int gs_setshapealpha(gs_gstate *, double);
-float gs_currentshapealpha(const gs_gstate *);
int gs_settextknockout(gs_gstate *, bool);
bool gs_currenttextknockout(const gs_gstate *);
@@ -177,7 +169,7 @@ int gs_pop_pdf14trans_device(gs_gstate * pgs, bool is_pattern);
int gs_abort_pdf14trans_device(gs_gstate * pgs);
-void gs_trans_group_params_init(gs_transparency_group_params_t *ptgp);
+void gs_trans_group_params_init(gs_transparency_group_params_t *ptgp, float opacity);
int gs_update_trans_marking_params(gs_gstate * pgs);
diff --git a/base/gxblend.c b/base/gxblend.c
index 50c02dfc4..5ac853300 100644
--- a/base/gxblend.c
+++ b/base/gxblend.c
@@ -2902,7 +2902,7 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated,
int first_blend_spot = n_chan;
bool has_mask2 = has_mask;
byte *gs_restrict dst;
- byte global_shape = (byte)(255 * pdev->shape + 0.5);
+ byte group_shape = (byte)(255 * pdev->shape + 0.5);
if (!nos_knockout && num_spots > 0 && !blend_valid_for_spot(blend_mode)) {
first_blend_spot = first_spot;
@@ -3054,7 +3054,7 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated,
if (nos_shape_offset && pix_alpha != 0) {
nos_ptr[nos_shape_offset] =
art_pdf_union_mul_8(nos_ptr[nos_shape_offset],
- has_alpha ? tos_ptr[tos_shape_offset] : global_shape,
+ has_alpha ? tos_ptr[tos_shape_offset] : group_shape,
shape);
}
if (dst)
@@ -3655,7 +3655,7 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated,
int first_blend_spot = n_chan;
bool has_mask2 = has_mask;
uint16_t *gs_restrict dst;
- uint16_t global_shape = (uint16_t)(65535 * pdev->shape + 0.5);
+ uint16_t group_shape = (uint16_t)(65535 * pdev->shape + 0.5);
if (!nos_knockout && num_spots > 0 && !blend_valid_for_spot(blend_mode)) {
first_blend_spot = first_spot;
@@ -3819,7 +3819,7 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated,
if (nos_shape_offset && pix_alpha != 0) {
nos_ptr[nos_shape_offset] =
art_pdf_union_mul_16(nos_ptr[nos_shape_offset],
- has_alpha ? GET16_2NATIVE(tos_is_be, tos_ptr[tos_shape_offset]) : global_shape,
+ has_alpha ? GET16_2NATIVE(tos_is_be, tos_ptr[tos_shape_offset]) : group_shape,
shape);
}
if (dst)
diff --git a/base/gxclimag.c b/base/gxclimag.c
index 309dda0c5..8ba10f446 100644
--- a/base/gxclimag.c
+++ b/base/gxclimag.c
@@ -1096,8 +1096,8 @@ clist_image_plane_data(gx_image_enum_common_t * info,
pie->color_map_is_known = true;
if (code >= 0) {
uint want_known = ctm_known | clip_path_known |
- op_bm_tk_known | opacity_alpha_known |
- shape_alpha_known | alpha_known | fill_adjust_known |
+ op_bm_tk_known | ais_known |
+ fill_alpha_known | stroke_alpha_known | fill_adjust_known |
(pie->color_space.id == gs_no_id ? 0 :
color_space_known);
@@ -1888,17 +1888,17 @@ clist_image_unknowns(gx_device *dev, const clist_image_enum *pie)
cdev->gs_gstate.text_knockout = pgs->text_knockout;
cdev->gs_gstate.renderingintent = pgs->renderingintent;
}
- if (cdev->gs_gstate.opacity.alpha != pgs->opacity.alpha) {
- unknown |= opacity_alpha_known;
- cdev->gs_gstate.opacity.alpha = pgs->opacity.alpha;
+ if (cdev->gs_gstate.alphaisshape != pgs->alphaisshape) {
+ unknown |= ais_known;
+ cdev->gs_gstate.alphaisshape = pgs->alphaisshape;
}
- if (cdev->gs_gstate.shape.alpha != pgs->shape.alpha) {
- unknown |= shape_alpha_known;
- cdev->gs_gstate.shape.alpha = pgs->shape.alpha;
+ if (cdev->gs_gstate.strokeconstantalpha != pgs->strokeconstantalpha) {
+ unknown |= stroke_alpha_known;
+ cdev->gs_gstate.strokeconstantalpha = pgs->strokeconstantalpha;
}
- if (cdev->gs_gstate.alpha != pgs->alpha) {
- unknown |= alpha_known;
- cdev->gs_gstate.alpha = pgs->alpha;
+ if (cdev->gs_gstate.fillconstantalpha != pgs->fillconstantalpha) {
+ unknown |= fill_alpha_known;
+ cdev->gs_gstate.fillconstantalpha = pgs->fillconstantalpha;
}
return unknown;
}
diff --git a/base/gxclpath.c b/base/gxclpath.c
index 9a57932e3..b2b946d68 100644
--- a/base/gxclpath.c
+++ b/base/gxclpath.c
@@ -369,8 +369,8 @@ cmd_check_clip_path(gx_device_clist_writer * cldev, const gx_clip_path * pcpath)
* or stroking.
*/
#define FILL_KNOWN\
- (cj_ac_sa_known | flatness_known | op_bm_tk_known | opacity_alpha_known |\
- shape_alpha_known | fill_adjust_known | alpha_known | clip_path_known)
+ (cj_ac_sa_known | flatness_known | op_bm_tk_known | ais_known |\
+ fill_alpha_known | fill_adjust_known | stroke_alpha_known | clip_path_known)
static void
cmd_check_fill_known(gx_device_clist_writer* cdev, const gs_gstate* pgs,
double flatness, const gs_fixed_point* padjust,
@@ -409,13 +409,17 @@ cmd_check_fill_known(gx_device_clist_writer* cdev, const gs_gstate* pgs,
state_update(stroke_overprint);
state_update(renderingintent);
}
- if (state_neq(opacity.alpha)) {
- *punknown |= opacity_alpha_known;
- state_update(opacity.alpha);
+ if (state_neq(alphaisshape)) {
+ *punknown |= ais_known;
+ state_update(alphaisshape);
}
- if (state_neq(shape.alpha)) {
- *punknown |= shape_alpha_known;
- state_update(shape.alpha);
+ if (state_neq(strokeconstantalpha)) {
+ *punknown |= stroke_alpha_known;
+ state_update(strokeconstantalpha);
+ }
+ if (cdev->gs_gstate.fillconstantalpha != pgs->fillconstantalpha) {
+ *punknown |= fill_alpha_known;
+ state_update(fillconstantalpha);
}
if (cdev->gs_gstate.fill_adjust.x != padjust->x ||
cdev->gs_gstate.fill_adjust.y != padjust->y
@@ -423,10 +427,6 @@ cmd_check_fill_known(gx_device_clist_writer* cdev, const gs_gstate* pgs,
*punknown |= fill_adjust_known;
cdev->gs_gstate.fill_adjust = *padjust;
}
- if (cdev->gs_gstate.alpha != pgs->alpha) {
- *punknown |= alpha_known;
- state_update(alpha);
- }
if (cmd_check_clip_path(cdev, pcpath))
*punknown |= clip_path_known;
}
@@ -528,18 +528,18 @@ cmd_write_unknown(gx_device_clist_writer * cldev, gx_clist_state * pcls,
cldev->gs_gstate.overprint;
*bp++ = cldev->gs_gstate.renderingintent;
}
- if (unknown & opacity_alpha_known) {
- memcpy(bp, &cldev->gs_gstate.opacity.alpha, sizeof(float));
- bp += sizeof(float);
+ if (unknown & ais_known) {
+ memcpy(bp, &cldev->gs_gstate.alphaisshape,
+ sizeof(cldev->gs_gstate.alphaisshape));
+ bp += sizeof(cldev->gs_gstate.alphaisshape);
}
- if (unknown & shape_alpha_known) {
- memcpy(bp, &cldev->gs_gstate.shape.alpha, sizeof(float));
+ if (unknown & stroke_alpha_known) {
+ memcpy(bp, &cldev->gs_gstate.strokeconstantalpha, sizeof(float));
bp += sizeof(float);
}
- if (unknown & alpha_known) {
- memcpy(bp, &cldev->gs_gstate.alpha,
- sizeof(cldev->gs_gstate.alpha));
- bp += sizeof(cldev->gs_gstate.alpha);
+ if (unknown & fill_alpha_known) {
+ memcpy(bp, &cldev->gs_gstate.fillconstantalpha, sizeof(float));
+ bp += sizeof(float);
}
code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_misc2,
1 + cmd_sizew(misc2_unknown) + (bp - buf));
diff --git a/base/gxclpath.h b/base/gxclpath.h
index 19e008c2d..b65bf7a94 100644
--- a/base/gxclpath.h
+++ b/base/gxclpath.h
@@ -37,9 +37,9 @@
/* segment_notes must fit in the first byte (i.e. be less than 1<<7). */
#define segment_notes_known (1<<6) /* not used in pcls->known */
/* (flags beyond this point require an extra byte) */
-#define opacity_alpha_known (1<<7)
-#define shape_alpha_known (1<<8)
-#define alpha_known (1<<9)
+#define ais_known (1<<7)
+#define stroke_alpha_known (1<<8)
+#define fill_alpha_known (1<<9)
#define misc2_all_known ((1<<10)-1)
/* End of misc2 flags. */
/* The following bits don't get passed in misc2, so are only limited by sizeof uint */
diff --git a/base/gxclrast.c b/base/gxclrast.c
index 2911ee257..5963d8530 100644
--- a/base/gxclrast.c
+++ b/base/gxclrast.c
@@ -2753,17 +2753,17 @@ read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
*pnotes = (segment_notes)(cb & 0x3f);
if_debug1m('L', pgs->memory, " notes=%d\n", *pnotes);
}
- if (mask & opacity_alpha_known) {
- cmd_get_value(pgs->opacity.alpha, cbp);
- if_debug1m('L', pgs->memory, " opacity.alpha=%g\n", pgs->opacity.alpha);
+ if (mask & ais_known) {
+ cmd_get_value(pgs->alphaisshape, cbp);
+ if_debug1m('L', pgs->memory, " alphaisshape=%d\n", pgs->alphaisshape);
}
- if (mask & shape_alpha_known) {
- cmd_get_value(pgs->shape.alpha, cbp);
- if_debug1m('L', pgs->memory, " shape.alpha=%g\n", pgs->shape.alpha);
+ if (mask & stroke_alpha_known) {
+ cmd_get_value(pgs->strokeconstantalpha, cbp);
+ if_debug1m('L', pgs->memory, " strokeconstantalpha=%g\n", pgs->strokeconstantalpha);
}
- if (mask & alpha_known) {
- cmd_get_value(pgs->alpha, cbp);
- if_debug1m('L', pgs->memory, " alpha=%u\n", pgs->alpha);
+ if (mask & fill_alpha_known) {
+ cmd_get_value(pgs->fillconstantalpha, cbp);
+ if_debug1m('L', pgs->memory, " fillconstantalpha=%u\n", pgs->fillconstantalpha);
}
pcb->ptr = cbp;
return 0;
diff --git a/base/gxgstate.h b/base/gxgstate.h
index e6dd92f75..90bd12da2 100644
--- a/base/gxgstate.h
+++ b/base/gxgstate.h
@@ -242,7 +242,6 @@ struct gs_gstate_s {
gs_logical_operation_t log_op;
gx_color_value alpha;
gs_blend_mode_t blend_mode;
- gs_transparency_source_t opacity, shape;
gs_xstate_trans_flags_t trans_flags;
gs_id soft_mask_id;
bool text_knockout;
@@ -326,7 +325,7 @@ struct gs_gstate_s {
{ (float)(scale), 0.0, 0.0, (float)(-(scale)), 0.0, 0.0 },\
false, {0, 0}, {0, 0}, false, \
lop_default, gx_max_color_value, BLEND_MODE_Compatible,\
-{ 1.0 }, { 1.0 }, {0, 0}, 0, 0/*false*/, 0, 0/*false*/, 0, 0/*false*/, 0, 0/*false*/, 1.0, \
+ {0, 0}, 0, 0/*false*/, 0, 0/*false*/, 0, 0/*false*/, 0, 0/*false*/, 1.0, \
{ fixed_half, fixed_half }, 0/*false*/, 1/*true*/, 0/*false*/, 1.0,\
1, 1/* bpt true */, 0, 0, 0, INIT_CUSTOM_COLOR_PTR /* 'Custom color' callback pointer */ \
gx_default_get_cmap_procs
@@ -346,8 +345,6 @@ struct gs_gstate_s {
s->log_op = __state_init.log_op; \
s->alpha = __state_init.alpha; \
s->blend_mode = __state_init.blend_mode; \
- s->opacity = __state_init.opacity; \
- s->shape = __state_init.shape; \
s->trans_flags = __state_init.trans_flags; \
s->soft_mask_id = __state_init.soft_mask_id; \
s->text_knockout = __state_init.text_knockout; \
@@ -371,6 +368,9 @@ struct gs_gstate_s {
s->get_cmap_procs = __state_init.get_cmap_procs; \
s->show_gstate = NULL; \
s->is_fill_color = 1; \
+ s->strokeconstantalpha = 1.0; \
+ s->fillconstantalpha = 1.0; \
+ s->alphaisshape = 0; \
} while (0)
struct_proc_finalize(gs_gstate_finalize);
diff --git a/devices/vector/gdevpdft.c b/devices/vector/gdevpdft.c
index 46f4d3121..76d69630d 100644
--- a/devices/vector/gdevpdft.c
+++ b/devices/vector/gdevpdft.c
@@ -274,7 +274,7 @@ pdf_begin_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
const gs_pdf14trans_params_t * pparams)
{
if (pparams->subtype == TRANSPARENCY_MASK_None) {
- int code, id = pgs->soft_mask_id;
+ int code;
pdf_resource_t *pres = 0L;
/* reset the soft mask ID. Apparently this is only used by pdfwrite, if we don't
@@ -284,10 +284,11 @@ pdf_begin_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
pgs->soft_mask_id = 0;
code = pdf_prepare_drawing(pdev, pgs, &pres, false);
if (code == gs_error_interrupt) {
- /* Not in an appropriate context, ignore it but restore
- * the old soft_mask_id. Not sure this is correct, but it works for now.
+ /* */
+ /* Not in an appropriate context. Do not restore the soft_mask_id.
+ Otherwise any group push that occurs following this will use that
+ softmask, which clearly should be NONE here.
*/
- pgs->soft_mask_id = id;
/* ignore return code, we don't care about this graphics state as we aren't
* emitting it anyway
*/
diff --git a/examples/transparency_example.ps b/examples/transparency_example.ps
index 812004972..8609cf9e7 100644
--- a/examples/transparency_example.ps
+++ b/examples/transparency_example.ps
@@ -5,13 +5,13 @@
systemdict /.setalphaisshape known not
{
- (\n\n%%%% WARNING: Transparency operations ignored - probably due to using -dSAFER\n\n) print flush
+ (\n\n%%%% WARNING: Transparency operations ignored - need to include -dALLOWPSTRANSPARENCY\n\n) print flush
/.pushpdf14devicefilter {pop} bind def
/.begintransparencygroup {pop pop pop pop pop} bind def
/.endtransparencygroup {} bind def
/.poppdf14devicefilter {} bind def
- /.setopacityalpha {pop} bind def
- /.setshapealpha {pop} bind def
+ /.setfillconstantalpha {pop} bind def
+ /.setstrokeconstantalpha {pop} bind def
/PageUsesTransparency false def
} if
@@ -37,7 +37,7 @@ systemdict /.setalphaisshape known not
<< >> clippath pathbbox newpath .begintransparencygroup
- .5 .setopacityalpha 1 .setshapealpha
+ .5 .setfillconstantalpha
.9 .3 .1 setrgbcolor
diff --git a/psi/ztrans.c b/psi/ztrans.c
index 2933e37a6..0b4ad2664 100644
--- a/psi/ztrans.c
+++ b/psi/ztrans.c
@@ -41,20 +41,6 @@
/* ------ Utilities ------ */
-static int
-set_float_value(i_ctx_t *i_ctx_p, int (*set_value)(gs_gstate *, double))
-{
- os_ptr op = osp;
- double value;
- int code;
-
- if (real_param(op, &value) < 0)
- return_op_typecheck(op);
- if ((code = set_value(igs, value)) < 0)
- return code;
- pop(1);
- return 0;
-}
static int
current_float_value(i_ctx_t *i_ctx_p,
@@ -123,34 +109,6 @@ zcurrentblendmode(i_ctx_t *i_ctx_p)
return 0;
}
-/* <0..1> .setopacityalpha - */
-static int
-zsetopacityalpha(i_ctx_t *i_ctx_p)
-{
- return set_float_value(i_ctx_p, gs_setopacityalpha);
-}
-
-/* - .currentopacityalpha <0..1> */
-static int
-zcurrentopacityalpha(i_ctx_t *i_ctx_p)
-{
- return current_float_value(i_ctx_p, gs_currentopacityalpha);
-}
-
-/* <0..1> .setshapealpha - */
-static int
-zsetshapealpha(i_ctx_t *i_ctx_p)
-{
- return set_float_value(i_ctx_p, gs_setshapealpha);
-}
-
-/* - .currentshapealpha <0..1> */
-static int
-zcurrentshapealpha(i_ctx_t *i_ctx_p)
-{
- return current_float_value(i_ctx_p, gs_currentshapealpha);
-}
-
/* <bool> .settextknockout - */
static int
zsettextknockout(i_ctx_t *i_ctx_p)
@@ -216,7 +174,7 @@ static int common_transparency_group(i_ctx_t *i_ctx_p, pdf14_compositor_operatio
check_type(*dop, t_dictionary);
check_dict_read(*dop);
- gs_trans_group_params_init(&params);
+ gs_trans_group_params_init(&params, 1.0);
if ((code = dict_bool_param(dop, "Isolated", false, &params.Isolated)) < 0 ||
(code = dict_bool_param(dop, "Knockout", false, &params.Knockout)) < 0 ||
(code = dict_bool_param(dop, ".image_with_SMask", false, &params.image_with_SMask)) < 0
@@ -245,6 +203,15 @@ static int common_transparency_group(i_ctx_t *i_ctx_p, pdf14_compositor_operatio
params.ColorSpace = NULL;
}
}
+
+ if (gs_getalphaisshape(igs)) {
+ params.group_shape = gs_getfillconstantalpha(igs);
+ params.group_opacity = 1.0;
+ } else {
+ params.group_opacity = gs_getfillconstantalpha(igs);
+ params.group_shape = 1.0;
+ }
+
code = gs_begin_transparency_group(igs, &params, &bbox, group_type);
if (code < 0)
return code;
@@ -674,10 +641,6 @@ zcurrentSMask(i_ctx_t *i_ctx_p)
const op_def ztrans1_op_defs[] = {
{"1.setblendmode", zsetblendmode},
{"0.currentblendmode", zcurrentblendmode},
- {"1.setopacityalpha", zsetopacityalpha},
- {"0.currentopacityalpha", zcurrentopacityalpha},
- {"1.setshapealpha", zsetshapealpha},
- {"0.currentshapealpha", zcurrentshapealpha},
{"1.settextknockout", zsettextknockout},
{"0.currenttextknockout", zcurrenttextknockout},
{"0.pushextendedgstate", zpushextendedgstate},
diff --git a/xps/xpscolor.c b/xps/xpscolor.c
index 980a71745..f8f0d6bf0 100644
--- a/xps/xpscolor.c
+++ b/xps/xpscolor.c
@@ -28,7 +28,6 @@ xps_set_color(xps_context_t *ctx, gs_color_space *cs, float *samples)
if (ctx->opacity_only)
{
- gs_setopacityalpha(ctx->pgs, 1.0);
gs_setfillconstantalpha(ctx->pgs, 1.0);
gs_setstrokeconstantalpha(ctx->pgs, 1.0);
gs_setgray(ctx->pgs, samples[0]);
@@ -40,7 +39,6 @@ xps_set_color(xps_context_t *ctx, gs_color_space *cs, float *samples)
for (i = 0; i < n; i++)
cc.paint.values[i] = samples[i + 1];
- gs_setopacityalpha(ctx->pgs, samples[0]);
gs_setfillconstantalpha(ctx->pgs, samples[0]);
gs_setstrokeconstantalpha(ctx->pgs, samples[0]);
gs_setcolorspace(ctx->pgs, cs);
diff --git a/xps/xpsgradient.c b/xps/xpsgradient.c
index cd59ba30c..60a828302 100644
--- a/xps/xpsgradient.c
+++ b/xps/xpsgradient.c
@@ -999,7 +999,7 @@ xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dic
}
gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
- gs_trans_group_params_init(&tgp);
+ gs_trans_group_params_init(&tgp, 1.0);
gs_begin_transparency_group(ctx->pgs, &tgp, &bbox, PDF14_BEGIN_TRANS_GROUP);
code = draw(ctx, root, spread_method, color_func);
if (code)
diff --git a/xps/xpsimage.c b/xps/xpsimage.c
index e08a068ec..e789b266e 100644
--- a/xps/xpsimage.c
+++ b/xps/xpsimage.c
@@ -316,7 +316,6 @@ xps_paint_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
return gs_rethrow(code, "cannot gsave before transparency group");
/* You do not want the opacity to be used in the image soft mask filling */
- gs_setopacityalpha(ctx->pgs, 1.0);
gs_setfillconstantalpha(ctx->pgs, 1.0);
gs_setstrokeconstantalpha(ctx->pgs, 1.0);
gs_trans_mask_params_init(&params, TRANSPARENCY_MASK_Luminosity);
@@ -332,7 +331,7 @@ xps_paint_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
gs_setcolorspace(ctx->pgs, image->colorspace);
gs_setblendmode(ctx->pgs, BLEND_MODE_Normal);
- gs_trans_group_params_init(&tgp);
+ gs_trans_group_params_init(&tgp, 1.0);
gs_begin_transparency_group(ctx->pgs, &tgp, &bbox, PDF14_BEGIN_TRANS_GROUP);
code = xps_paint_image_brush_imp(ctx, image, 0);
if (code < 0)
diff --git a/xps/xpsopacity.c b/xps/xpsopacity.c
index 64e414bd5..acd0b2c70 100644
--- a/xps/xpsopacity.c
+++ b/xps/xpsopacity.c
@@ -78,9 +78,8 @@ xps_begin_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
if (opacity_att)
opacity = atof(opacity_att);
gs_setblendmode(ctx->pgs, BLEND_MODE_Normal);
- gs_setopacityalpha(ctx->pgs, opacity);
- gs_setfillconstantalpha(ctx->pgs, opacity);
- gs_setstrokeconstantalpha(ctx->pgs, opacity);
+ gs_setfillconstantalpha(ctx->pgs, 1.0);
+ gs_setstrokeconstantalpha(ctx->pgs, 1.0);
code = xps_bounds_in_user_space_path_clip(ctx, &bbox, use_path, is_stroke);
if (code < 0)
@@ -125,8 +124,12 @@ xps_begin_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
ctx->opacity_only = save;
}
- gs_trans_group_params_init(&tgp);
+ gs_setfillconstantalpha(ctx->pgs, opacity);
+ gs_setstrokeconstantalpha(ctx->pgs, opacity);
+ gs_trans_group_params_init(&tgp, opacity);
gs_begin_transparency_group(ctx->pgs, &tgp, &bbox, PDF14_BEGIN_TRANS_GROUP);
+ gs_setfillconstantalpha(ctx->pgs, 1.0);
+ gs_setstrokeconstantalpha(ctx->pgs, 1.0);
return 0;
}
diff --git a/xps/xpspath.c b/xps/xpspath.c
index d2eff223b..19d6506ce 100644
--- a/xps/xpspath.c
+++ b/xps/xpspath.c
@@ -65,7 +65,7 @@ xps_clip(xps_context_t *ctx)
void
xps_fill(xps_context_t *ctx)
{
- if (gs_currentopacityalpha(ctx->pgs) < 0.001)
+ if (gs_getfillconstantalpha(ctx->pgs) < 0.001)
gs_newpath(ctx->pgs);
else if (ctx->fill_rule == 0) {
if (gs_eofill(ctx->pgs) == gs_error_Remap_Color){
diff --git a/xps/xpstile.c b/xps/xpstile.c
index d278bd8fe..eea48f478 100644
--- a/xps/xpstile.c
+++ b/xps/xpstile.c
@@ -388,12 +388,10 @@ xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
/* If the tiling brush has an opacity, it was already set in the group
that we are filling. Reset to 1.0 here to avoid double application
when the tiling actually occurs */
- opacity = ctx->pgs->opacity.alpha;
- gs_setopacityalpha(ctx->pgs, 1.0);
+ opacity = gs_getfillconstantalpha(ctx->pgs);
gs_setfillconstantalpha(ctx->pgs, 1.0);
gs_setstrokeconstantalpha(ctx->pgs, 1.0);
xps_fill(ctx);
- gs_setopacityalpha(ctx->pgs, opacity);
gs_setfillconstantalpha(ctx->pgs, opacity);
gs_setstrokeconstantalpha(ctx->pgs, opacity);