added test+fix for transparency group stacking
authorMatthias Kramm <kramm@quiss.org>
Fri, 21 Aug 2009 19:15:37 +0000 (21:15 +0200)
committerMatthias Kramm <kramm@quiss.org>
Fri, 21 Aug 2009 19:15:37 +0000 (21:15 +0200)
lib/devices/ops.c
lib/pdf/GFXOutputDev.cc
lib/pdf/xpdf-changes.patch
spec/transpstack.pdf [new file with mode: 0644]
spec/transpstack.py [new file with mode: 0644]
spec/transpstack.spec.rb [new file with mode: 0644]

index 7b5f1c7..bda4742 100644 (file)
@@ -66,7 +66,7 @@ inline gfxcolor_t transform_color(internal_t*i, gfxcolor_t*col)
     col2.r = col->r;
     col2.g = col->g;
     col2.b = col->b;
     col2.r = col->r;
     col2.g = col->g;
     col2.b = col->b;
-    col2.a = (col->a * i->alpha)>>8;
+    col2.a = (col->a * i->alpha)/255;
     return col2;
 }
 
     return col2;
 }
 
index 2c90c92..2f4a2cf 100644 (file)
@@ -1877,6 +1877,13 @@ void GFXOutputDev::restoreState(GfxState *state) {
   }
   if(states[statepos].state!=state) {
       msg("<fatal> bad state nesting");
   }
   if(states[statepos].state!=state) {
       msg("<fatal> bad state nesting");
+      if(verbose) {
+         int t;
+         for(t=0;t<=statepos;t++) {
+             printf("%08x ", states[t].state);
+         }
+         printf("\n");
+      }
       exit(1);
   }
   states[statepos].state=0;
       exit(1);
   }
   states[statepos].state=0;
@@ -2654,11 +2661,7 @@ void GFXOutputDev::endTransparencyGroup(GfxState *state)
     
     this->device = states[statepos].olddevice;
     if(!this->device) {
     
     this->device = states[statepos].olddevice;
     if(!this->device) {
-       msg("<fatal> Bad state nesting in transparency group");
-       msg("<fatal> Notice: this is a known problem, which will be fixed in 0.9.1");
-       msg("<fatal> In the meantime, please convert the file with -s poly2bitmap");
-       restoreState(state);
-       this->device = states[statepos].olddevice;
+       msg("<error> Invalid state nesting");
     }
     states[statepos].olddevice = 0;
 
     }
     states[statepos].olddevice = 0;
 
index 83adec3..234952d 100644 (file)
@@ -992,3 +992,21 @@ diff -u -r1.5 -r1.6
        }
        dx *= state->getHorizScaling();
        dy *= state->getFontSize();
        }
        dx *= state->getHorizScaling();
        dy *= state->getFontSize();
+@@ -3824,6 +3833,7 @@
+     out->beginTransparencyGroup(state, bbox, blendingColorSpace,
+                               isolated, knockout, softMask);
+   }
++  GfxState*old_state = state;
+   // set new base matrix
+   for (i = 0; i < 6; ++i) {
+@@ -3835,6 +3845,9 @@
+   display(str, gFalse);
+   if (softMask || transpGroup) {
++    // restore graphics state
++    while(state != old_state)
++      restoreState();
+     out->endTransparencyGroup(state);
+   }
diff --git a/spec/transpstack.pdf b/spec/transpstack.pdf
new file mode 100644 (file)
index 0000000..f0682c6
--- /dev/null
@@ -0,0 +1,90 @@
+%PDF-1.4
+%ê~
+1 0 obj <<
+/Type /Catalog
+/Pages 4 0 R
+>> endobj
+2 0 obj <<
+/Contents 3 0 R
+/Parent 4 0 R
+/Type /Page
+/Resources 7 0 R
+/MediaBox [0 0 612 100]
+>> endobj
+3 0 obj <<
+/Length 107
+>> stream
+q
+
+1.0 0.0 0.0 rg
+
+0 40 m 612 40 l 612 60 l 0 60 l 0 40 l f
+q /gs0 gs 1.0 0 0 1.0 0   0 cm /mygroup Do Q
+
+Qendstream
+endobj
+4 0 obj <<
+/Kids [2 0 R]
+/Type /Pages
+/Count 1
+>> endobj
+5 0 obj <<
+/Length 337
+/Type /XObject
+/BBox [0 0 100 100]
+/Group <<
+/K true
+/CS /DeviceRGB
+/S /Transparency
+/I true
+>>
+/Subtype /Form
+>> stream
+
+0.0 1.0 0.0 rg
+0.0 0.0 0.0 RG
+10 10 m 70 10 l 70 70 l 10 70 l 10 10 l f
+10 10 m 70 10 l 70 70 l 10 70 l 10 10 l s
+0.0 0.0 1.0 rg
+0.0 0.0 0.0 RG
+30 30 m 90 30 l 90 90 l 30 90 l 30 30 l f
+30 30 m 90 30 l 90 90 l 30 90 l 30 30 l s
+1.0 0 0 1.0 1000 1000 cm q
+1.0 0 0 1.0 1000 1000 cm q
+1.0 0 0 1.0 1000 1000 cm q
+1.0 0 0 1.0 1000 1000 cm q
+endstream
+endobj
+6 0 obj <<
+/CA 1.0
+/ca 1.0
+/Type /ExtGState
+/BM /Normal
+>> endobj
+7 0 obj <<
+/XObject <<
+/mygroup 5 0 R
+>>
+/Type /Resources
+/ExtGState <<
+/gs0 6 0 R
+>>
+>> endobj
+xref
+0 8
+0000000000 65535 f 
+0000000013 00000 n 
+0000000062 00000 n 
+0000000166 00000 n 
+0000000323 00000 n 
+0000000380 00000 n 
+0000000878 00000 n 
+0000000944 00000 n 
+trailer
+<<
+/Size 8
+/Root 1 0 R
+>>
+startxref
+1040
+%%EOF
\ No newline at end of file
diff --git a/spec/transpstack.py b/spec/transpstack.py
new file mode 100644 (file)
index 0000000..6bc151c
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+import sys
+sys.path += ["../scripts/"]
+import pdf
+
+# a test for transparency groups:
+# form xobjects used for doing transparency groups can do savestate (q)
+# without ever needing to do a corresponding restorestate (Q) because
+# their content stream is self-contained.
+#
+# Test that this doesn't confuse the pdf reader.
+    
+file = pdf.PDF()
+    
+page = file.add_page(612,100)
+
+group1 = file.create_object("/XObject", "/Form")
+group1.stream = """
+0.0 1.0 0.0 rg
+0.0 0.0 0.0 RG
+10 10 m 70 10 l 70 70 l 10 70 l 10 10 l f
+10 10 m 70 10 l 70 70 l 10 70 l 10 10 l s
+0.0 0.0 1.0 rg
+0.0 0.0 0.0 RG
+30 30 m 90 30 l 90 90 l 30 90 l 30 30 l f
+30 30 m 90 30 l 90 90 l 30 90 l 30 30 l s
+1.0 0 0 1.0 1000 1000 cm q
+1.0 0 0 1.0 1000 1000 cm q
+1.0 0 0 1.0 1000 1000 cm q
+1.0 0 0 1.0 1000 1000 cm q
+""" 
+isolated = "true"
+knockout = "true"
+group1["/Group"] = pdf.PDFDict({"/S": "/Transparency", "/CS": "/DeviceRGB", "/I": isolated, "/K": knockout})
+group1["/BBox"] = pdf.PDFArray([0, 0, 100, 100])
+
+gs = file.create_object("/ExtGState")
+gs["/BM"] = "/Normal"
+gs["/CA"] = "1.0" # stroke alpha
+gs["/ca"] = "1.0" # fill alpha
+
+resources = file.create_object("/Resources")
+resources["/XObject"] = pdf.PDFDict({"/mygroup": group1})
+resources["/ExtGState"] = pdf.PDFDict({"/gs0": gs})
+
+page.header["/Resources"] = resources
+
+page.stream = """q
+
+1.0 0.0 0.0 rg
+
+0 40 m 612 40 l 612 60 l 0 60 l 0 40 l f
+q /gs0 gs 1.0 0 0 1.0 0   0 cm /mygroup Do Q
+
+Q"""
+
+file.write("transpstack.pdf")
+
diff --git a/spec/transpstack.spec.rb b/spec/transpstack.spec.rb
new file mode 100644 (file)
index 0000000..8f6226f
--- /dev/null
@@ -0,0 +1,13 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "pdf conversion" do
+    convert_file "transpstack.pdf" do
+        pixel_at(15,15).should_be_of_color 0xffffff
+        pixel_at(4,50).should_be_of_color 0xff0000
+        pixel_at(21,52).should_be_of_color 0x00ff00
+        pixel_at(49,51).should_be_of_color 0x0000ff
+        pixel_at(80,49).should_be_of_color 0x0000ff
+        pixel_at(23,77).should_be_of_color 0x00ff00
+        pixel_at(70,20).should_be_of_color 0x0000ff
+    end
+end