mirror of
https://github.com/storytold/winprint.rs.git
synced 2026-11-15 06:44:28 +00:00
test: cover resolution in visual regressions
This commit is contained in:
7 files changed
+264
-43
No files matched your search
@@ -22,7 +22,7 @@ endobj
|
||||
endobj
|
||||
5 0 obj
|
||||
<<
|
||||
/Contents 15 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||
/Contents 20 0 R /MediaBox [ 0 0 595.2 841.68 ] /Parent 19 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
@@ -47,7 +47,7 @@ endobj
|
||||
endobj
|
||||
9 0 obj
|
||||
<<
|
||||
/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||
/Contents 21 0 R /MediaBox [ 0 0 595.2 841.68 ] /Parent 19 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
@@ -57,7 +57,7 @@ endobj
|
||||
endobj
|
||||
10 0 obj
|
||||
<<
|
||||
/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||
/Contents 22 0 R /MediaBox [ 0 0 595.2 841.68 ] /Parent 19 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
@@ -67,7 +67,7 @@ endobj
|
||||
endobj
|
||||
11 0 obj
|
||||
<<
|
||||
/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||
/Contents 23 0 R /MediaBox [ 0 0 595.2 841.68 ] /Parent 19 0 R /Resources <<
|
||||
/ExtGState <<
|
||||
/gRLs0 <<
|
||||
/ca .6
|
||||
@@ -83,79 +83,136 @@ endobj
|
||||
endobj
|
||||
12 0 obj
|
||||
<<
|
||||
/PageMode /UseNone /Pages 14 0 R /Type /Catalog
|
||||
/BitsPerComponent 8 /ColorSpace /DeviceGray /Filter [ /ASCII85Decode /FlateDecode ] /Height 1340 /Length 1741 /Subtype /Image
|
||||
/Type /XObject /Width 1052
|
||||
>>
|
||||
stream
|
||||
Gb"0=!=8`+$j<9i?i&Aa-s0]RWiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!WiE)!lK\Zi3%&_~>endstream
|
||||
endobj
|
||||
13 0 obj
|
||||
<<
|
||||
/BitsPerComponent 8 /ColorSpace /DeviceGray /Filter [ /ASCII85Decode /FlateDecode ] /Height 1340 /Length 4220 /Subtype /Image
|
||||
/Type /XObject /Width 1052
|
||||
>>
|
||||
stream
|
||||
Gb"0P5n*f:!!=tRRg'8uQ:kBr4U1uFcNO=D[!iA_d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&Z$m&\d'8$-!78!"$NSPYIL?/&nGjWV-ZT~>endstream
|
||||
endobj
|
||||
14 0 obj
|
||||
<<
|
||||
/BitsPerComponent 8 /ColorSpace /DeviceGray /Filter [ /ASCII85Decode /FlateDecode ] /Height 1340 /Length 6809 /Subtype /Image
|
||||
/Type /XObject /Width 1052
|
||||
>>
|
||||
stream
|
||||
Gb"0HT`Mqo%)fC:^[r=dJhmrM[I<OsG9m!.h'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbU)H\+bFPS=tFPS=41pB6NkdjQql+0YGBjcL&d<2'ldrh9nd_Gq+U?b"bVX$FfUk&]47FusN:"OfV8HT>GMluq&S$)W6P6Mdn(1$Z+2I6&K-4MMf/@t85CqB%u9H%"U=`iIIflZ$tR5D-5ZKSkqZK\qr121-IAC5OlACG[nACA6paeJ)baenAfaeXIkP"!uNP"jPVP">``,`Ai&,b(t6,a/EJ8/>M*8N'lK8L=ltO=\!2PAIhuP=uls+B`gB-eWUt-^cfq5dKUb:U95r:GQWlJRm/NT4HDnT4HBc!m.2&509\f509UO"d2=+I?I=VI?I/($RCY5q]qZ6q]q@0(.]3HpIR8KpIQ\@/<DEomZVIumZU<_=<Lagh'^lth'\UIYX#MX\kfWr\kb(q@"Dk9Fe<3nFe<3m^]MWPlTWFflTWFdJH_3*f6rfVf6rfR!t-B4Y59K6Y59K."r9`F?2$oK?2$o;%4mSl]'bbu]'bbLine truncated
|
||||
endobj
|
||||
15 0 obj
|
||||
<<
|
||||
/BitsPerComponent 8 /ColorSpace /DeviceGray /Filter [ /ASCII85Decode /FlateDecode ] /Height 1340 /Length 6736 /Subtype /Image
|
||||
/Type /XObject /Width 1052
|
||||
>>
|
||||
stream
|
||||
Gb"0H+TVQs$j<j0Dn<i-E$-Dcg[8r)q3sp:XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2V@XI2V@%%9_KXI2VLine truncated
|
||||
endobj
|
||||
16 0 obj
|
||||
<<
|
||||
/Contents 24 0 R /MediaBox [ 0 0 595.2 841.68 ] /Parent 19 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject <<
|
||||
/FormXob.298c33c3c6cc55f95fec6c1b69c06d3b 12 0 R /FormXob.448be173554bae444ae91aa9b861b6a9 13 0 R /FormXob.a7f7db8f04525a170e8f3ceee7ad286b 15 0 R /FormXob.cafd156e5d6f3418e559c97d0678de28 14 0 R
|
||||
>>
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
17 0 obj
|
||||
<<
|
||||
/PageMode /UseNone /Pages 19 0 R /Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
18 0 obj
|
||||
<<
|
||||
/Author (winprint.rs) /CreationDate (D:20231114221320+00'00') /Creator (anonymous) /Keywords () /ModDate (D:20231114221320+00'00') /Producer (ReportLab PDF Library - \(opensource\))
|
||||
/Subject (Visual regression test input) /Title (winprint.rs visual regression fixture) /Trapped /False
|
||||
>>
|
||||
endobj
|
||||
14 0 obj
|
||||
19 0 obj
|
||||
<<
|
||||
/Count 4 /Kids [ 5 0 R 9 0 R 10 0 R 11 0 R ] /Type /Pages
|
||||
/Count 5 /Kids [ 5 0 R 9 0 R 10 0 R 11 0 R 16 0 R ] /Type /Pages
|
||||
>>
|
||||
endobj
|
||||
15 0 obj
|
||||
20 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 855
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 852
|
||||
>>
|
||||
stream
|
||||
Gatn%9lJKG&;KZL'dI^L*erM(mpk@S#cWW;qLZX3C7Sa'S]XMPr-N&-G$(4TD+h-F`A>ic47fU$#X2hrI<YfqQ14cBJg;bR+>mm^Ddcp(:m*Xn!"q;/,bT0gFF\PDB_YTj!ZH(p9JB#_=KmJ$&j]a<p1hDUq;ac<p]T$cpa"8\nbK`^;)Fu/JTH*&84#BdTAXR+fH4;,J(^>5^/r@!;#Z"9Wdcf:MaU8=a"s5T=>PeX\(Ob(ZT.0$(FlO`)2_MS]N3hq9gBXGE%n?>(eu<87S=ooNP])EpF?t-CUR-/\.lYD`\e[/MCrWhqbfQY]NH0gPf`aB`mOtC?3,q.ZK!/BW/)U/jl8rA;)>osD,iGeW7@&hR1i3W/=.04M?aP)9n^ZI%V&O+jjao",@'W^'a)UdpZoJFJrA72N]YbFWO@\2f*&;?eQ)k=U8BRBZ\bLl@TaE*k0m(EMkUp*H]$k&Q(3^n/)WkO&`>#XMrqBT`bR5/<of2_YQqDF")C(C(O9Y)]Z<0Dr*&L^LDNFm\\@dt)$t:.1j>T&K"<e,_!G??2(rB=JVeIb26qXJ2pEs5hp':[@T5P?oc-REkCd%o*c<1lXG@[L7u2BPp3@_lrL3A!3M$`pI@X)%HZm6)[^3hVZlQuJeRkEX`!<ai.@[ab,U7nR]Zg9PH1Pu2ZT%V;WHNFU1R`BYL!)!eL-e0rA*IWZVS5/?>NX*HgMQm'<@pVD<,/d[$lbYuXWq^+/t1#6QKJCpCcMUqfK@`s"!ah=_fDQUmUfmR*O7+bh[ADNcNTIA]i*WU*gO1fVHbcsoA%pA$/6^&WfLf\Wj^WheaZ``)VEWU:M4"b2st@(Sph!]i\)8Vo3V~>endstream
|
||||
Gatn%9lJKG&;KZL'dI^L*gWAMmpk?(#cWW;qLZX3C7Sa'S]FANr-N&-EEJ\O*D<YKg$_$bn'%jF,TiEQ+.iQL-+mS.+@3O=e3ZNJ#Kq-7OO2V[K#hYY+I"+G"16fc_ll*;KL4k<"="1'$"\sdX^H3+@lZaJaWsW35)L!\HP,H<Gi@!p$jI4&-&N6BPgAj-f^JMc4M7akO5I"u4",SDH#n6cdE4jMs2u:CX<Q1[mXDjO!&GMOK9n&>:)Sq%l+C'Qi_0nA:gblUKF7Vo)D/&?N\?V&P1@0eaqQ[:-RLAj?30'por>;rNFZCr-\+-K_`(977lFs"KY8Y'+s(oT`(Qoam'M/1M-`("qp8AD_h;4<=[+9%FI"-YUZ)g\N$^mQf`Xlm>!h=NYF6%UG3=_`EU!EW:SHk1Fh)S5H9:h$ES5)%qR#+Z5b2X>i]lar3[s5\0e>NUUuA%8BtU@r=e*U=\W[)$boHe5ijNMqCM(6P\?I`$%"[0*mHn'J#.`GL.HAt8!TVdH\(eYOip-6g%soS?QI&lfRU>BtA-VYX&gf#qemK]XWCF>BmCLuji`e!^+U@6f?-N]*YtqkDj3N]9SeU^0nGr+Yg`CVNd4\);kJR9QEMW2fd@R8of\9!VY20ZHb%eU_%H<"E%%L$RN?BHuB=r'SrL;(1`Pf+YEfkBD2a?>A0!o_Gk'3OqcuH9pHA':ZGtPM]/n]!EolG5_OMtJ(_8al@BV)\n\:M.LAB&,)9#,6oB7M(nVg>sf6ksg2&)>]@09"5*1u>fRYjgAe!hnYUF,bO?[+.'gHE!B$>;mqW*oU1K4EFB-e[DT?a*QXYVZ)!)o;]NE6,R./+TSj`BCbRl~>endstream
|
||||
endobj
|
||||
16 0 obj
|
||||
21 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1241
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1240
|
||||
>>
|
||||
stream
|
||||
Gatm:9lo#Z&A@ZcqWPHUaaAU!(2"Y#X1Z%s6e,LjO^Se7$V?J6D>)S"O+]3#(!<LZTNZlChg=08h(8gFhlO6W28I`N5(7(Y36[](,`sdmL$REF0[>o+5WC]#0d+>P,ootL,Y(pG*)YL):ehU?PQoBhd%!Jb@<k%&7""%S(7t]8&YCkRGPLqtgI[Nt.-?W7;GK3:#%hX1S,(Y?VTh$jo`pk4LY;LKXd)O`\bs3M$9>%c"0fB_otV)WBY1q/a.S^\`mcG3[,[0tiKblA>RU>OB@"9uo)rm_^]PniAh+BV2IZRfO&b_5_m4N@n!eH&6h0LnB^g22r3M)GOcki_L)VfrJLY->[K?hpruW.uPB<kAOg2Rm)RM4e=t5Oi>[A/u!WdTjdr1lIn)4&OS*T=#7pqQ5O!aQ7NtausW<YP84_EZn`ZmrK<G+n[pr/=a^+Z=O3[1Ef;Ym6B;uuU_QI'c:(Nl.i4]'.P<8(G5A5_k(8/Xjl&?ItL@I<C(qdQ,WLS=Jm/.^Zq0j5JH4tK.'`Vt0[=79T6MAY$#GjcI<)#(&HqDtE]\>P>hOcEm*,*gX,fH!s&adaZ?.t.VH;gG!rK2TmH6J\@<,=ZZ#f`4uBMLcXf"F??l-BDRF/,)F^ki8")@o);`m&aVQOCTNZLI\4cj'#m_j7^R]MpE@/CaU7..^3.:2BFp9LNN2&_Y:(NDo-U!\P8NS?S\Q=AXW?OMY[GdK$n=71cuZgNJp=qUSBPW=Bro+3Yp>P\;nON/?WK&*Ac`\]r;Tq(eQkMe*S'_W(%4YC>_uXK4#ZH"r]nj,(A"'PXc2:5g/ZeX$-mim"$+\]5sL.Z_'=`?Z_CEb+Qcq:8E[(pu.t5>(:G@^.Mj`g2dE!,Uh#IE82FV&M.nQ'aCq_9#8(f]*Ga$?u665=I'P7*I;4VAmEAbHZ_NgIbfG/Wku/Qku_0R#;oG;33#s0O&hs/19$GD9$.n,O%#>l!"!ok(3o7U?=_\.Z$B;thB[B8H"[QSYJ-H\g@rFR@4MhSGhS?"Qhj/9lO-gL/48d$nPtT6PC*E&/<m""C)[cV"ZF(WKd)R&C(GL^pC1(nNIK9'7Gr7$L$)9NOpmo0b1CbaU..\[/ZO7d!ee,:M/A)&p1QkuF]0#N*aZ^X=[B_N2V;@*ncG9nOrBV%FSbkV(j]&&>2#dJrbtot:r8QMiO."F3:SQ9R3>T:$hu+np;?8Dj<]Q<OK'@YDAcb"9RJcAb2ICM9`>2_!,rS~>endstream
|
||||
Gatm:9lJcU&A@C2bgA<7%;.o9]u?u2'M)HG'$uOi[()hgVFZH;Cob=bZ_V8-/0d,>-"0>947BkNh3fEQ6uVGYEW^9gJ.J7aOMbN2.%,b-=1DS\(iiU0!or',KtrB#8m81"=[B41==2D5TWDTB1hT-r%^gr>q2F7q9e/;E%N#FiN_JoXl$(qKOIRc,6ki/4XAuLW^tHT<ZnQEB\SHYF`A^nhn%Cc];(%Y/(JF:S+<kfYFdlnOp]4(<XWGt8FQ2YO2PlhMg`dRV1N"N-!5H&AagHSc5[:^9:\fR\g;3Nc?Tu=o>s9(/.UV,gG#L7p5.MS8qE%LPfg/eRCa,NlmO';KMJ4ml"j$]S$+*(2P@3'C<X/rb(rf:GO#:0KQ$Gt%K95nqO*A'PrS,TiI*<f`aGrcsp_8c'N6YThiq_m`pYWH?0F"O(:Q!`"@iG0WN9Z59'm(+&5*amV;kDhY\g`QCWKO*1#e?$hS(NaheGB;FL2)ALd@Y9jER!TN\Oh[r:gEBh#OoqS/Idsc'k+2_lh-pLhSh#[;^1Xtmp$21@C',eY<sq$,@NSdBd5)rij(V>ddFXM9XHO<>k)=JS(bD^)E!D_:o%@gBZqkS+WR0_),Y':*MZs&[*M[Dj4ZZD$\f?dC/D/JII2K+WtplRB>sYu%";G3;Qc&95.RDaeooJ=`Y;"sZ6R[WT<3UYpg3o@LH=;X:Kh+1+uJ&Sb2%e_r<i9CMLrZPGVC<Y)2nnl#@kh_=GL<*L34?a@9A:n*JS]MVPAL%,6XR$^1cZ@%;f!1&pTMRV$Mg[3"69O"NX$Adt*\f$/.X7nDU];$NBC`)mTG+3%\c-G/0_lO?^p]V]ANC#9t"ZY[)SSghpAfK`#os$Ns!sTY]!r3G^!@jgM?%(7SD5m"apXBM9dO=CLEL+ed@%ZIHFHlS*4[c=bY6qp/JPfM66>eJj6?NCkoEWVsV<qZa'r:9lp[ej*Tj3h\"^MoMZ:n6oJ^e01fBe8Eqd7@$#K95lPe?M_YN_44@ep6TmTPD5C71ipnFXF-TQG2'U>TW^qL_D:jcjne6h`$2&G=(G,C@8=Lfh>Vg)Fjc@YE*kEr=R=tf2qoT*VlY&9j3+)-Z@#0B+,PMU0(ra9iepmFZA,6Yb=;f`5&JouXNN1Q(qMiI[Xt:uAMBbVrWe-`<kXeO.@E7;QqV7@)&Q_9gkuil'-%H;e6qNT6:`^*62Kr+MP>#lh+Rs\nh2TV]cRm;pe_6-rrU.@DlN~>endstream
|
||||
endobj
|
||||
17 0 obj
|
||||
22 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1295
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1299
|
||||
>>
|
||||
stream
|
||||
Gau0C9lCt@%)),5i2LC2@#*fj?3@RJoMF$up0n<9j476>a_CVCqdu[qR9_[9F"d`1=7da5aPi5fOMaTNn,5&iq]5Y1Z]HU&mR]NfgAOW.m3WU6&.>aXnj/'`C%-h:&(:QZ.2<>],)$Y3;hu-Q/ZR7hNpbe!Y_Wh*Z[F.Ae\2C2Mg`\.6H(G[.I`UnZ9"UkpIsK%I(4U844/7oo6U?0fA5ZrgAOUTG8K)'Z^Wu@[D`,9/r#A)hejP(a9F_^.QMaVC,N.cZET[+'YUc4519$FMh*H)P\;%b8JJM9p_&]IiFH\/ZCaMlBCU74JIADi2q.tg2lJSO63oaub%A^4,OJoY[n*1D82XB,h(2i#\"@V=lpO_[`6kFJNB!9km!R6F-:K6!0d07**QK-^Buhh[^j#>lJJ\!>Mat03aaR+k1%bXi'i*0I@&QXX_(O3Xl4&&t+i2iD$\PoW!k$%ITbcA,c8N%N2E],G7q-H]j,f?;/%)Ho2Gi>%c*,RCAKc$73KjV849FCpioooA?mm1P0%j$tM5-IK-qWcfqS?'nFH0X=2/KpI9BnLuj9L0m"F?&-6T+#NdT([9:)n8Pf,lm0ZWaSS2LI1mQE>$tQN^g"M=Wp9PQ\apdS-(A'm(*:?*^*8eKV,ng/&]4mL%cJPB:tRAc[4&l'A\A:MfO08>+R:2,n)B/7$5=Xq89GLt:li4/9]Inau]3'*nAmp)#!o!i$Hk=Bqjoa`3><I.)2kP;ci*[Id1e\S[Z4lC-OcTNW<FVtN(T$88SMO8B8gRE5dkiLRnG-/4uLAC74Q2d)]nWo7-V8%pG*mURTDha#aFKj^@s]5r6r]%tJ!f=mpii_7qH1=G'ACj.XtNE<[(bTL^DkZd_*SkZV-=kAuKh>PcM-jPJBHFoH`3IoQlp`9^UC`\H9<n,_UijW#EY_ff?7dNRH>XMHJKZQ>AZ"u+U@1,NH(p.>f(/sEZWjc*;J&/?q@@,Rt[Wk9=<`lF-kD`u(2+&4'VN'6)j);2idT@5b=RYB-\B:rj_p>tfRJ3&eCPuJElA3DcP&]D]fO?i?[GAFIKpqTJ(,_IpSbTH*Z&\\AC7,:IBW9_:9-dfc>Y8VP&Zt:/:_DrdVnQFfIs[n#dsI%)E*3`MX].Cb[O;8`4YOF"_4`4B'(bAsc\F]Q#Ho^.L?b`piM4@Nb$p*,>`2W+"&9m%(130r,S.1,ab0"A%Z^c=K&l()gh-FeVo13Nc0>aGRnp!>k0K*DQfI,bQ&d<hqsj=Cp'H0-iHTQ-4aoN?rSp,GT?p+-^crV,Z<bRdqA0Y,Q/V~>endstream
|
||||
Gau0C9lCt0&A@P9QrDDp0]gOJo,=:hV2(erYnoch*OW=b85@X+hoD"Jj@W.n*,GXZC%OCV3.-+LKcFDS^Mfa$hJ_VuT7o[Io0D<ge)ja.Bf!#mKNO%1P7Kur8V8[<I%1Z`RSmRXPUVj48l=99.NNa*n8:QR]RZN9.nQnc<B+<J,;'cR?9(PBU$RG*$++uTn*`Hq^[+_f*SnCM5Q8&PrBQi:C%LaJFQVn$^3Z8&W'_V=X+\7D5OQUI1mh*[W*;dB.8>tZ]d0B:NA8mUcU05fQA#'*1lf9qMHRJla_7)]1:81V:*PCu+@Sd\A`o6eR9F.#LN+o#?C<*84d.\AEfB[W#f\`&%FpiT9K2Rt:08uh+t3`UkYh+DS4e$K?KOhC63_FG8IIu-5(uBC1/#Q@QlmFXL"'T54J^CLgI]pTW?4C.E/Ks:6nQgnp6\<mk,IGSF=LE3MCfF!C6TWO@D/JIT%LRi*fA:+=BrpMCJV$2;:f,>hOMioRaGUg0Qr,2"m)*tc0JV.ahU\=$8&KQ9G9oPm2/F]dIeYWMfaP6Ae#/eOa83B5,8mJC.e]i)Pr1'Zs0Dsait97`1_'qaMVYu@-:Sc!0qh6D3Z.M_CfUHmh8>cW#J!,1O4Ua@+2O!G4Hss<S)<..(2WgK:\r/3jg$8J7/a:dLp913/L#1-%^,r;F<=q/^qu*cJ$X'2RI@cC539<`RF:j9H<7P4>B6a78#K\lrfEC%Z`$P>9)GgmYdJK]+g^iZM^%lp)4S5#njH(L1R3Jf>67V6<7^$Jjt!?q7e*)?=W&R<W1f[Flo]Yh$dqD9<PtJaAp!+X'J\4RUOjZ]Hu<=@q9B4TRo.Eof-3.VDhL@Y;('W2k@W%41K.CYNk_,**'t`Y4n8p@io,[c]eOu]YNI-7*Yh'T"t(cpgu5.0OdJ!4Z`Ku<X`f=Xe69(PUj5i"Fl.N$rD)<JIL.,Zj[21Xk5*CAS-(EL$]8nk7r19G`=;HdA[ir[fI7ODQm`?7Qng^m,IZh=<,Pp*NZL%bqcfnXr#"-]P<jiAC-6=lsck;(0?WW"i%kh33KFU#2EQPmJ.(s%HaZ(5ACch:nM!XBg@UmeM\Waa;_-O,UL@oK@Y2OW/1)m;nl0\^HKu"krhdlE4H^ZW`2(_/l%dQXh7mU$jANI!\n&I;>JS"jIp=(MEsCj->Kp`NNnjJ(#,H3AAG0sDXiH`Dt4HDRQQNlcbi9NJ`P@&g!04JT>V`q6"hqpRhr#@k0NqBbAi#Vjl;3shOd!f5J]6!O1WkTs7&>bqgVp:_++F>rt4mDI1<+=?i>54Yl~>endstream
|
||||
endobj
|
||||
18 0 obj
|
||||
23 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 8881
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 8946
|
||||
>>
|
||||
stream
|
||||
GatU9ac:5YESS=4\1>Jjii&`U@;E[P`de;5km\e7":^3R8U:)Y8&VC.k.?CF-XcIq=0L:)\u*]o+l[Tm-2`u"n)+-'p%k.r?GH<Jr6"-oc0nuL?1%=05J7!hRkIhqg%p##V2T$^Fk'?jXk-A+J,'\;Nj12eUVCWu<JL0J03@P;]RK_Fot/!<!^us=D\deIj[oB5YJ0Psot6(.b%5kWB?aDYP1k//o7tq)rr#XMrn@t@rV3:_?[qVBa8c/,Vr*"$a.NCsp!(7d^A7*n]Z-L!md`b'r34]<%J?@-rVjE1qZY8&f1]39XB,+a`bb=>VtI*oZLY&/]5jM=<N_Tf_`CK'n5p]X^4]Y<#d_P9D_UM"WRMu@=fZ#>n_L1rY@2as3q;I\@9-!A$p<B=I@jKBf.+=!7^H!aKqi>1hC$kN<GNMXdGUg>'\;DV;Y(eYjk+83aB[_roD>=Q^2dF@2O`2YQai+Q5,hC4Z^#!p0l.FC+1:k6#%Q9M3"6IaDT8Tp>)t[<(u8:KR*jL'j0RqC3R)Z*3Ec]"[ass?.d_XVZX,XSV^6t!F1b9Thl:`<!6M4W@]l0RHH^&/.GG,f"\3-5.M\TE;d/F#"cFHg.A]_4N/*HrjdNUMfO+]0orY'2>JGoD)f71/&5:9;;GHC1V/^XY(>A+kWH3W+J%1<)dM:T8Shb3hXQ98Ci:F*08o-20fc\M/mrQXN?$#/\ap^69^mI8I6r!hS1<1_!-bbQ:/D''\ehuAk6SM0f>l/bj#TQ>sSO/)BcS]"DFn$#l%F]QGNY"nPP=n#:IS;6c.sTCB;L7F;ci3DG3A2AM)=jB/D$QDPQ1:4UDXPn=.pSMXXtVKca.,c6U.tb+'3:tVHh[kkNQZVY*PTr@m]ihSCsOQTCQ0Aj"^WU20]V+;i'4I8(0d51ED#3K>1.9^'hl;k*AW>c`;rY,oeEH"n%^CQ;\Q'.qpS-dH1frZL&`UX\A4*Ug`&pSZkj+T<\8$*1_"@$I7gVNPVltWn@t4rD"_r`c)qA6(kYtT$f#fQ:24+O$`^X8#r8))_U8VKd*\mP@5)ZSmHGgr?>7@GVqPe"<8'a9ofaZXIQ_fF&H$X=jm5bZ@0:_j$5l1$,BI^@PZN3akm;RNMQQAW1'&6Eq>6tLq[<V_&K"V[_U;VnVj$?Akm.\5&u.]U0V4IHGA7nE.1MUK@-5p0oYiBfU""gpn3bsZ7gu2I_<;.I'.[lVfjddP>m$47#f^W@$KDgajtt)3<=[[`DE#eY>0UWkUEK:??;QH-OD+_"kN@7g1LH&iMni";,[eif:1CZ47Q1\50IMQ"iA%=b0A'k"n/2;R7MnO)O%HH(RTs#k4MmjV]u8&0CC)/GAR+/]`a_WAiL=oPlliIn%:uk1S]'ep1buO$)]'?89RfR#f<c5QHAG$M#X_;W5,XQ!Y(W2&1E4QUi,9Z#U83Z>@>2uJNZ8EG4dX[U;*+,uR,>6t=kDk_f&rPMSG\=_pGCGY3Wd(:S8u4'MYTDg+foI$KLkQQb4UXX2*1.a/oVgA+&VP"a>(GbbF)q$Nkf/TGF3XZXf3QAi<$L=hksH%'ho#sCH=_3YC0*DPY2NU?kE6TI='(s.2>4!(3=gCf$+BdZT[G-/tAl%*AI?+=m;\E>XYRUb+j]O?>&nOopOB@9!uHUP`QpDH'U=LMS4@m;VQo`,'NMgqnQLRK'`k#Y%U*1cAn525/qY=l^Bgj(kt4Vhi[cQ6*t[koS'ASABkIHoPg@t2&Q5u*B`[BO$CGH0r$Z%bonk[1hjaip@&T0iAR'sK/XA:@!RNb:N%qQE?38b'b#_i+j>3-#A^DNL/-UhXPY8/XpS^SL?UCQ&Metn)KUP)5kl@3?#Za9UPGaLe/4-5hC$kF's6R-LA-5GL%#RN=elKI4r>T()WTGnP(i=+&2A/6E.th\O#]q+VU4:kn?cG/^cghu3]F3u&5:?$.u]_\0dkP_ESZ:U)KH8%i+oC+_\aVrO=_UK@Hi9=Pb+)-GO$XYdoh#"9RjV[(:m!Gf`K#Q<].8$muq4W46ZJe[sR6t+&g%c7f*I4l?8Y9$-t'>eokbCYi570)]#t_biu5d=O<FX4<4R*gkb>b0Y+N_JS1SbJlV4Oo6Mt(B#5Zk;_8'm`cRTaTI[H/3Hr;=Ao*.:1iJc(.X)8H]fLFb&Z@SK.WA/gV-M8km.*Yg`Y3tX<^s8QnJ#o/G0M(LHH%8^7br&scAX21bh2=88Er&#rGFYR0_8n:ZE@T=V_qu"aJb\1(?BoRQ?At`EoF!"'b#gi,=(\Cnd(uZg^d)j/B*!CJ\*\kdO]-gA_[dG@6,>]YnAU(;(t0'%$o[n<H"7IeIqJ!)(SBR.!8:%2mUZ5@9DQm-"I<9+9p<$jK>(lL(?C#m6^LX3dbnZKjFgpnVo;EG*IH\@hS'&@f^7=)&K.CHaGSpacn4'j[SGYX3B45q?VJXY:iQ(,DB=hHX1Yh[g!s//4Z[@Y]W"3$o5tq\njI3_fMca?SS`COc.:-'0H`u\tifa;'moJ)*)uk]%-\,.l(sf)M_aX4,qU#)Oj3LBrl'6qrDRXb18o?i5+/B).h7i!2d!2ZXJgT&MXC_(Saif[I+.u8_6!WP>m=aaXa,s_&s0#q&2'"^LE27=i:_nMpN:G.n<d47U+b(oh)<d7UV,Dn-urKd6:rCm]]gRmO_rTZq2S_0QPi)ifSOp`YIgo@nGf\W&IEn\7aTe=Q,i/@L.UF#,1Z=dmfR8DVMj\#nqlXFDLZe?)cZB=`tK(&LK?2@?\;ckcV;I'="+G$kZnl0Y#)8QLG(M;e5'uH!hDWU(L$8*GMK\L9\1G':dlIYe\MP8H?^Z@h6lPY*6a5*2J]#'/9UOPVgO6XKmX1K^7R3%'a1a0U9=M_PAL4`hm<k1otV"W#IjD)mh\HP&4\XMSl[4*K),')4?G(#=s@_eK#FkgS%^[+bZjjUUMGrY-#*ad\A?1XN6Q!Fp*`WCu\+D0^B?O/HSjE7L@[2[+iUMpkE4*4%?G>U8!+c^oi`f(riHHL1qjK6sulA4N"8*FC0!'Vu%@_[ps9p%Y#e*_uZ0Dj/B$]1IZtR^``31<E`-QDFA2Q406F'2bO5R(o/Udap*p0rE_&tQmsFV":"`IZY[=u\1rY7*2Wst0HK\Im'<lZ/JL028"!3u$lo#)>rLIGh!R8a\7&LtNY,^X_7T'>V8U^.=Amd"29LR90V`npSn>ReKRRo"f!f-G(tO4KQ;pGP<RN<SaLm*M(sJl#-kY.S[Moi?LLGTm7Y8HG(E$f'pM$f_c06o.8qMU+//`"blE/=>Ymu^]8MIRe6P!5e[+F+r2f5X7LK]WpXiMhD#amSG>4u62Grs#s0jKjH8b-8sf41'J;kbNS__iR+/4if8&jH9PZ+_7=^t<Nl%!K,!5=JOn?q-@_A%9KgP?7o&h2<E]C(@SE*#Pt^AWs[]4aZOY-`=)3-jKs">\0*Z=.-MYk/h=IM*&_/YtZ(o`@]QI_TM\/),V.XDNuiT9O0pj@-0L(/'<Hph,W->;Gq4b2r.]C_B%[P(c*k7;_"NH'R&:C9FGlKD"Du3QAV^9AtC>.f!f-/R"k6bSZ=W9C(]On&ZaY@##$8$S'@[=PC7d_QH`@W`p.`+!Rm-=FnKD*1UYaX2g7'k7N!lhf6(Y'&##FcgW$T&e"[>=L>-(K6(AUW2B5M:DoM!bMu_<<pPc]bQ=S]c1cc&GgO)$^K.51pqeYj^mBo&8D6.Wq#VZ_*Tb2FKZj<EDh7;NIh%&s))KUD%UdeiZ^t(V*D(KSF#V\71<F+'.bKY)][.##h`U+KCL5\?W!m@\D!mE2#VFCkG/]6VTTratB/h3s4K34B<daG_=dW!%.CkUs<^l0]A"VXLC-a,#C7[Du#Bj3#YImIVqmrgJT'uF)A#GsoR0.\Qp.PV8JG:*F,@4Y$#WN[^PA]IZuDSq&9bR!cH&B>;!APZplVr;'HZ+M+C>Tp#D1.n%d,`S28__t2FdU/*p,T3Gp!4:L]U]])?r0N<<<CVgm=gj;qoA%hthi@56.]tI.V<(p:J?,gmQke_t<*X.C8tJ$l20/BFe6([i&R^^j%p:3kPDji:CtLEn8q94g:h>p%?J,Sdbja]CEfUi@&;W#GB;/'0<Z,pT)eDGE0GU`q.g)]klY3`mW@?A!62h7p*u4E/\PkjLdrSGtI61t786(hSZ?A*6$bbXfktqKjnspr)X=_Q(8$AMQ)@P>J-ic&bGmPfn)>=ui;c@1[4%=b:O\N,SjB](Z0nuU'`Y*KS!J;>!a=ardYHT7<*Mu=E0KCBE-!R`WFj%77mY5_X*%tZQk6L/I-\j/;jUh^e_\A'?2a9pF#Y\<``o'CG7^J7Jj[Ua9J>l*D7VeudbXE\kfEQJ_EY0-eLX;-md<D^GjERlQ;9D=8emu8GOI*6X$^_T(+/N3B#&/qX_$s1R1cbI'4%d$hbS9`rE$$rs-?mcBO&@S1K+jlf`)bNI`j`3+[pc^C/qPjSPV[*6V29d+YYeXS(P(b<JKeK@pb\A,qjUJ9K$p..ZD98X89`C(KQ7)-h"W3?/M]VOV.Hi"bcR+fTGVqU9U]*(,0IW$N_V2.Z?/6l?edLQGjoR7Y*06dm%V7'r^fJ^iH;&nPDd54:gn]rE6='q\47k^5b[CpX32]p#1J>dp5Vm#!X#@Bj^mgYUD_%G7b>b1N`&beHHe4gS/Mf@H#o4PPDd63]GI?h1Vui('b7QmEWMQ/CW.WIPQVjFm2_Hs"N3_.2Kg#sQ?BM,UQUPNXIEog`QlDGSS[DDj8p`6k%#..NJ"e'UDmg'j<?9Vlo*KR7AiD=So>d2>QCT9M0T\`e>0okAjIAJCZHZn6]F'0^#(5nbhs,E!(`l!'BGJ#/U"GD;78kF!WsBPgmL^,+Nj>.kE3gh:ae>8+9I$Q243[JmA#c$TYS*of\W#20!_)*"`b3>AZGBu=bk"KHc6f@"`aX2?5HU64Y'hAb&[6'oPkJ-fokRhLoE6KCOUS8+;[9\CA$T@`DQaC'@[u?ol1QX3&iO/*lBh#hE2iDqR?MLine truncated
|
||||
GatV$993r!EJ<TM=.E-LG]:l.nM(K7A7?YlBUFY7aFXItE?s;\cd,d1Ze3^_K"HP8JfD2LkIVuulTnRRh>*?*:Y,RGp(+@Yhgb=qofqS?0!DI-pWDmZ?=3ZnoabDXH0:?mYLgCNd4E&hFVJWWou"7G^;iaa=RV^!I+bfLH1ga2]p.+Zhn4F4X"V9I+8hqmjcq4P-,9>3j84+_UQr=MKth;ur*IQQ?iAsV\,Z*<fDkBs2rFZ"a4K4]rqS5)r:'Tes7kX3]tX?hf2o`@+4lmD`a#*3.g`:VIg5k<YJ:%ueUE*qcS\YO'WVst9k1VX:!rgLYHm`"@o69qoi:KmV3,-6hY:1nHa^koBuI*Xq@0df3TW+cR'eCZ]%!<trAg`fXAVeVJ6=>G1%=^6l?uRD^/mn:L+mlgNhT7[:TF.Jcm;(/6^u0NI*?<=8"F4E0Qgp/E6n>DViflINS6^deiQsCO*[GIW,K$!,0tT^_\9o-8+""F0_SfnP7:s3)*^=9H;&(jhO7RQ1E,u=]?Hl8PFC`!-4D\`RB8>oI$JlIe?&,O$D(`1ZXcpKNr,@9UHR]Ng;>r$MRh6demhJHSMEDM_;m@+Q\r!@3N_pkH%kU3j\j5HAj"ke.dpMPaM(^[!%V;I*Qr=;370cck]u?W3N&=o@nu(?gW6)/SLnueE:"/hO]-R9MoRMrU^Ra8fR6LTQ$;O0HVf.D+D/prUiL5=3EchIkk*c_m,9:3)DI;@S&fXpdNP@HqOH&E>_kPAV<;+\Gdn&r8B->p#+o[g^NFN4rZ'Au(LggHj?C,m#`4U6jf[!c0Vqi'na$cFOY_$01./L#Lc`,bX,P)pO=6&K@[Lb]98j/SQrIc*$o+Z6n:[WPaW>=$Ne;<p"@;[17CAZQ3Mjj%&>BU0CJ`$g8\fg0.YM%B[X,e5>%pP?mq8$1W":`Q_PI:1VYZZYm>MAq]<$ifWr;0,l=<_I6*T+S^5\9CL2!&A+_9B9UrC_<\Fo``>%LM94X^$^aos\MqM8_l$:2n)>i;4NF&EZ;+Vl_H>EtHCF:jfM'RIj/X3H4+[*bHt_CB#H`@u]Ubb\%0>PC.G@?e%hW/f8>Q*W\\KFPkQ)RA`k8*8N50<]Q:oYd+.U;2-m.5:AjS8e8fZ"t8sL`$.MXQ3k`h&$_j`ndkX(^*S:j#NsPL_(M"C%1rnnbMehI5)qa0X]kLD_(5>,=Z*0#d#d''.[lVfjdpT0d;:p]327@@Vip%UrHe1#h^MU)s1V3jtc@hKnp:5c.bLn,R4//5,X7$.1A"cR97NHs44*3R#RM"a=cHA1+.cs_IHKM,::@S@YVh-&Ms$";E4(gI0sDegHc_Ekp0;!:e2bq2L$^Sn4_jsVpu=m6BJJiTPX>"MccMn+[i<9EHr.)qAh=/&7T-`Z=uZiF.X"=mL0@EUP,]13=P?<i?CmoD^B<69^fXIkddL<VfW,rOD3J5]\)Ec=iY#IP5uh;g,=p,)]_N-@no$=+N,s9=no%X"R/+J>S.KUaaHt//O:6b%oG)W\iA,k0M#KZ^^Z,c]jiB5642CV09oSfgZnMnQ%XAqbO(GF-SDXV_a32`XE.5EK>SfJ\<m,\;_\E.&[J;EgZAk;fcG2QL^137*ZgNs)L\uJK.&T3*eYpdE@<WFa,Fc,@h.0M50mFBSAXb9U=?&_Mbt6C2*00n-Y>%N`%Xip,/0$!S/.kcaL4U-][Rdt5<M=a$jIlE*19`W.6W&kBoTqO7O`uE+#&%8WJri'9$"@ED&Sei*Y+nr7"ZB21'<pKep$?Kl%ZI%GVDHB3=ML6R.580ep(=;_fT5A^P<;-G>*ePY`NR[d<ID`b(K/MKn.N:7Ysq28n0Oi\PK5<"GBll5FC4.UPNm0<!J!]"\-TQNU]YRffK:&aLGl[?[HjJSo^>/#Vc`M/QWe!a..D)SRT/.XEec=EM.YPMHAVJ`R^pFMua@$\&o_$N!LTES>M1`9IW+P2&R!8(c[+=9RjV[??Ok%DN?W8QPs&dqkSJeh.$+APE1&7-9e;[+#Sr[Q8o]9OE<Uu`#K3-+nM9ucNd7Z5,P\"CNgrn`cl^-1$a(1M,h&76["=ALR/qSm*eTY*-514\*#>Z-3b?WXs58$BcAkbZ1ZAPMh0o`%]9t)G;1SN\PoR2J7[^=7BY3`=@(ee."rff(B9MhER3R4PmM8%grCA_(_U:L3S.>.kt4*[Am2GoK-;D(Pp7:cVJ45hd$m%,0d=Q]gWc*A1:-.$9?Dl0]J-lM,/eB\"tN'V,i]=?1@a-1VD0:5DGT5rN92sTC1=_/#]*1abJT)f\Le3<\NbU1GW_@IO:Y(QZXqfUWH7?M)lohPL=Pc.9C?4Pbbl&.\dH'[1C.e*cF>B*IY.#?oFX&!?^-\Z;`Z,>N#:Y]=9'7=`_u)IO*8Mu<Ip!'VWi89AispV#T/Z,0/'k'(D1^A9.m6qJ-!Q.87aU`(%8C71<Q,uCceiLk"p?Bh*S[NlugH!'3l!=F\0QL@j^5%`3uRdX&k*-Z>I/ka0_We=p3;V2'Spf@\[0iB2^:t6&^u)N&'Yf!/$9tNi!]36,^4j@#RQ8f"0-43-VKWR1'<4gST2=_B9N+RPn8%]eGas@hLLg`Xj'Ki73t@VU<sRVBR4;dX*;OgjOf-8%fuu/pCF1jNaIkIaTQgf"cd#D'L@+#;bRp,.<IgR7lf$1f4fugn&c2>sm<D?t4g;]umdG.@M270=b:8]4Yu;/&Q&"a3Dlq'OsOe5__usAYpHQDIc,Ph,PO*#SFC2;K"D8JJDpGg:U+%b[Nhn@;mt:Af,HQZ%KC[Lf#!",0#Vgdc5Cdf1e9l^`e]b+C^Qt<miB$%[KQ>63mf$1Z#^:#[f,tVo0^pnQFn?ATouDiD-)jIT2m-Fa0'd=6)`/i=0uP&_k<&gLQO16NW!dg)JKP&:28CO[J?pC%PG:gU4G40HHntAbK5h-)9ft(\P.p4*b<O6:-U_p-8bB;&YH%HJAdPN`d5CTgl*rLD?)E"s3ZOg;@a:_ci=LIj*%c2:(3sK^jmh!d?K%,:%q?q[SB-Zc!?>EFZ2RK:+RJ#\DL0X0eC-grRplp/`j)O;f)FN[V3T#(Ne2]imU]b'4I9$Qb1aZLoj!`W/VN9P6JDfQP=29kN'\T,*/-p5PK!#8+:qgKlYYL9SIKI@W>M%.C]!.(>!3mP;tO'#0aP98-*>gkcX'mP(A\h*'#)FVK/WDS4sul5u`CUZ0S"g+Wt'>7R'W#,/sV5LF&*aR!Hj%0nr7P_<ue9'l)DMbLG=/Bc&lAPU8[-A)oR`n"<Kab"TC*k%&N0SXh6+sq"s.5V\%+iB%IpTnQa38_a0b&$':Z#j8cZL!=5k)ZM$Lq?!1]cfed-J8g.LHSZuR)4@bU80E:/4of/m/$@6a"-T1o'SQW@!Ps.W5sf*AM>#j/DJC79JYA\[<o0Cr+Of/_p.6hJAE49P.=mfHTWQ<RPnJl[npu]bdbe@F0;fbA(R_j)P]S(ZPu@N[Un,mG]g_TS^AQhg'B-57[\?(-"a<4=`:_&"u(=&R:Xg/dZA:VZa,Nt&5):@Wt1Ea;I(i-<VM,[mlWso^$Xt=J]"b\mEPQn%)[<G#R;aeV[M(Y(-J2bQL-d[hJ];g<o;QPc$IdCahg2-Ab2[2j8F-2Ab?Mh^8jX(T;cHdEcX1Wqeb1$#;?G7Q"<*hC9hZn_>.J"UHsQbd')HeAG7;k8?CWMnTm9=c-pV3**3:pag,&_FNV[`"qf$jNsACbcSdH"?HWkV0WMTk70%u!d"XU4=m_q#h$J&<(_&eKT)=:6NQ(teeGN_.`ago^=>i'c<S;K<EqR![>53f>M$kD/@UpN""kHi&$^b',VD9-E*d:)@Ajoi=_MD-4:E*cI[8:&ad^mTLn0YGWjQ5c:#2=SOQAl1seWX("@H3=)a3quNm1O/,6XnTLH8=Lf1"Q6<'SM*8<mM.B)'q`qg[8kYE/Yq[KX1F]CQ_P<UlB]S,L(iY#R;YbgW8B0XKj304fEAKU9tgI+qTD/=f'AXP"/3;_F/qcAMAp:%/ZYdC%tgolrDK-1e**7#2c77iNOlf`^B?M.K1!U6"j#q<Z.aq98J*h<t8gs*/$#%BJN1t3GC?kon076H96i/H5u[7N"Xu=[Z13`*DE697;Np"6^:Lm]!;kObj^7anTqg#np9@?4KJ(8bSI:3S_q[@Ml5]nEEBYjXUL^HK@=MeO/9k>D'\rY$;ss]k&iRX%:Q-+99#:m(:jmn8L;J.CKD5dlXK0f3r<\[R+[4qZF2%=*khEd'H%N-67<429P^rVR\u*kN9!K-6oZWE65XMl4t%D_ADCZ'5FTG0,9hdrHUNB-_q[Sm_J3>!9P6a!:i]%VbAP^2<A*1_\VoHN3<ijg>lMO/s5]Qa1*//@+/UaScMVA;,+,M?NPUYkNFjJ4b)]RUJ>l,LMq/NqM2:-Pg4aOK>QeQ:%iUIFoN`sn<`:Wpf#gE0CU2T130^`F$Hbr<O&dl`_4a9Q_$ul1K?;e*hpKS80N5*'L1o'nRb[j(GdMJl%/,&1$6+SJ7`1\M`jf&%Jf3"ZR5JU)`*`[`N,.MVR%B]oEqEjV1c>$><\Au4Wtm*V1*]W,]=oMT$W,bT9T?E(-5oS$IMjkG.i6#=2)dWTZTM%-N\![L(P++@-oModN<MLnS)mMi"Yfi!hlq6d`aZh=SrQ]$Jl,<tm0/)U(D")I-l8OQG/Eq6-+*s+LKF20;D*P=ClWg_#<%QR'[I_Z;XST7>R<2&hQtRG^K'c;NnI%8#j1E#1&=$X#)bM^Z^#P39NG]/aW`#S_\9bZPD_\"*T4qXUW0Ub_>WTY,+*L1gJ;s*iht(QjiHKaPc]&5\N1tQQB6".QH;QL;]Ta0D$j')R==3\._,P5/tY4M[@/q>b_+9^CmA6.1K91:eb_cqh$ce!(SETg2^t(aDR#L=NnGVe#R4>Nj:a8QM),%Tdm\9X#Z[eH7Gor!`_ub]gGO!`#b6gAgH3`8M`jj[M-P_>9NOCHO@)B$B^oYRM-L&0l_7(PB4[$p/GHnL+W$irQII+Line truncated
|
||||
endobj
|
||||
24 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 587
|
||||
>>
|
||||
stream
|
||||
Gat=g95i<6&:j6F'm"2lb4U]VIU$<\3,ej3+V&j=*+oRoPJs"X`NR<R\'jsnZmD$$aRX`MH0dhYA`3->2ZRc2\@P-pK";'66::\PhURlV68fkfOk#C5PU4m%ntm<tW3oq[Zjt`p+>>(*+bH5W];Q(>N3[JT';1iRKYe_eAKD@'RKTB=M4?um4[XW"B:m(j8f:ZD$N1akB1bd0GQ%C9*9uuh?Q9o@\6Qu:3LNGSTN$un+2]E++(=69qSDi34Ct0b65[1^^8*ma0l/Lo@!?etr)jVqcu+\<bGIq.7M=.7MH<m2A%qb"2M/T"8jsIhN6IjU/sTd[N/uDoWe&]&I<pmF1iq@qa7j*3s,=j;U?-h$$`7+>-D=G`\d:rD*KnGSI,doJ%K=nT-(/gqQJ(ir[hO=fgl*DcQ_7*Q-L5sB=>>Q5/b_,BCHA<>-"\74D5FM?:#u;[Qq*UG5&A5I0'*CspX.;EKC*L0\5$cc%VTEoSVejB)d7:EE99KVnlU/5I1S&5HM7%cob4#6ef,_ZPW%5Hm_AX-Qht2(Gn7[drGC2Q:>P!<htQ.2?%4fhQHid&<eoM[#(c%m@mU*F~>endstream
|
||||
endobj
|
||||
xref
|
||||
0 19
|
||||
0 25
|
||||
0000000000 65535 f
|
||||
0000000061 00000 n
|
||||
0000000142 00000 n
|
||||
0000000249 00000 n
|
||||
0000000361 00000 n
|
||||
0000000476 00000 n
|
||||
0000000681 00000 n
|
||||
0000000786 00000 n
|
||||
0000000895 00000 n
|
||||
0000000972 00000 n
|
||||
0000001177 00000 n
|
||||
0000001383 00000 n
|
||||
0000001645 00000 n
|
||||
0000001715 00000 n
|
||||
0000002025 00000 n
|
||||
0000002105 00000 n
|
||||
0000003051 00000 n
|
||||
0000004384 00000 n
|
||||
0000005771 00000 n
|
||||
0000000676 00000 n
|
||||
0000000781 00000 n
|
||||
0000000890 00000 n
|
||||
0000000967 00000 n
|
||||
0000001167 00000 n
|
||||
0000001368 00000 n
|
||||
0000001625 00000 n
|
||||
0000003561 00000 n
|
||||
0000007976 00000 n
|
||||
0000014980 00000 n
|
||||
0000021911 00000 n
|
||||
0000022323 00000 n
|
||||
0000022393 00000 n
|
||||
0000022703 00000 n
|
||||
0000022790 00000 n
|
||||
0000023733 00000 n
|
||||
0000025065 00000 n
|
||||
0000026456 00000 n
|
||||
0000035494 00000 n
|
||||
trailer
|
||||
<<
|
||||
/ID
|
||||
[<b4f4b7def201a8dc448f13edf7db5997><b4f4b7def201a8dc448f13edf7db5997>]
|
||||
% ReportLab generated PDF document -- digest (opensource)
|
||||
|
||||
/Info 13 0 R
|
||||
/Root 12 0 R
|
||||
/Size 19
|
||||
/Info 18 0 R
|
||||
/Root 17 0 R
|
||||
/Size 25
|
||||
>>
|
||||
startxref
|
||||
14744
|
||||
36172
|
||||
%%EOF
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,51 @@
|
||||
//! Validate the visual fixtures and comparison using image operations only.
|
||||
//! These tests do not install a printer or submit any print jobs.
|
||||
|
||||
#![cfg(all(windows, feature = "test-utils"))]
|
||||
|
||||
mod common;
|
||||
|
||||
use common::{loader::load_pages_from_tiff, visual::VisualExpectation};
|
||||
use image::{imageops::FilterType, DynamicImage};
|
||||
|
||||
fn fixture() -> (VisualExpectation, Vec<DynamicImage>) {
|
||||
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("test_data/visual_regression/data.tiff");
|
||||
let pages = load_pages_from_tiff(&path).expect("load visual fixtures");
|
||||
assert_eq!(
|
||||
pages.len(),
|
||||
5,
|
||||
"fixtures must include the raster-detail page"
|
||||
);
|
||||
(VisualExpectation::new(path), pages)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unchanged_pages_pass_visual_comparison() {
|
||||
let (expectation, pages) = fixture();
|
||||
expectation.assert(&pages);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "page 5, score:")]
|
||||
fn downsampling_to_96_dpi_fails_visual_comparison() {
|
||||
// Match BASELINE_DPI in utils/gen-visual-regression-data/run.py.
|
||||
const BASELINE_DPI: u32 = 300;
|
||||
const DEGRADED_DPI: u32 = 96;
|
||||
|
||||
let (expectation, pages) = fixture();
|
||||
let downsampled: Vec<_> = pages
|
||||
.iter()
|
||||
.map(|page| {
|
||||
page.resize_exact(
|
||||
(page.width() * DEGRADED_DPI + BASELINE_DPI / 2) / BASELINE_DPI,
|
||||
(page.height() * DEGRADED_DPI + BASELINE_DPI / 2) / BASELINE_DPI,
|
||||
FilterType::Lanczos3,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// The comparison scales these pages back to the baseline size. It must
|
||||
// reject the lost raster detail, not merely the different pixel dimensions.
|
||||
expectation.assert(&downsampled);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//! End-to-end visual regression for [`WinPdfPrinter`].
|
||||
|
||||
#![cfg(all(windows, feature = "test-utils"))]
|
||||
|
||||
mod common;
|
||||
use common::print;
|
||||
use common::visual::VisualExpectation;
|
||||
use winprint::{
|
||||
printer::{FilePrinter, WinPdfPrinter},
|
||||
ticket::{
|
||||
FeatureOptionPackWithPredefined, PredefinedMediaName, PrintCapabilities, PrintTicket,
|
||||
},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn win_pdf_visual_regression() {
|
||||
let _ = env_logger::try_init();
|
||||
let visual_regression_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("test_data")
|
||||
.join("visual_regression");
|
||||
// WinPdf preserves detail more faithfully than the EMF/XPS paths. Use a
|
||||
// tighter tolerance so downsampling the raster-pattern page to 96 dpi fails.
|
||||
let expectation = VisualExpectation::new(visual_regression_dir.join("data.tiff"));
|
||||
let actual_pages = print::print_pages(|device| {
|
||||
let origin = visual_regression_dir.join("data.pdf");
|
||||
let printer = WinPdfPrinter::new(device.clone());
|
||||
let capabilities = PrintCapabilities::fetch(&device).unwrap();
|
||||
let media_size = capabilities
|
||||
.page_media_sizes()
|
||||
.find(|x| x.as_predefined_name() == Some(PredefinedMediaName::ISOA4))
|
||||
.unwrap();
|
||||
let print_ticket: PrintTicket = media_size.into();
|
||||
printer
|
||||
.print(origin.as_path(), print_ticket)
|
||||
.expect("failed to print the document");
|
||||
});
|
||||
expectation.assert(&actual_pages);
|
||||
}
|
||||
@@ -30,6 +30,28 @@ test_data/visual_regression/
|
||||
└── data.xps
|
||||
```
|
||||
|
||||
All printer backends share these five-page fixtures. The last page embeds
|
||||
300-DPI raster patterns (vertical/horizontal stripes, checkerboard, and
|
||||
diagonal bands) in a two-by-two grid covering most of the page. The blocks
|
||||
are generated at their final physical size to preserve the 300-DPI detail.
|
||||
Unlike vector strokes, these exercise image downsampling in
|
||||
`Windows.Data.Pdf`: rendering at its default 96 DPI loses the fine detail.
|
||||
WinPdf uses a tighter per-page visual similarity threshold to catch that loss,
|
||||
while the other backends retain their tolerance for registration differences.
|
||||
No separate contrast test or backend-specific baseline is needed.
|
||||
`tests/visual_regression_comparison.rs` checks the comparison itself without
|
||||
printing: unchanged TIFF pages pass, while downsampling from 300 to 96 DPI
|
||||
must fail on the raster-detail page using the same threshold as WinPdf.
|
||||
|
||||
### Pixel alignment
|
||||
|
||||
The page is A4 rounded inward to whole 300-DPI pixels (2480 × 3507), less
|
||||
than 0.1 mm smaller on either axis. This avoids renderer-specific rounding
|
||||
of fractional page dimensions changing the phase of the fine patterns.
|
||||
Ghostscript's XPS conversion also explicitly uses 300 DPI: its default
|
||||
96-DPI layout grid introduces a visible phase offset when printed at 300 DPI.
|
||||
Neither the pattern frequency nor the comparison thresholds are reduced.
|
||||
|
||||
## Determinism
|
||||
|
||||
Byte-identical re-runs are non-negotiable — the fixtures are committed and
|
||||
@@ -53,13 +75,14 @@ The script is pure Python 3, but it shells out to a handful of command-line
|
||||
tools. On Arch Linux:
|
||||
|
||||
```bash
|
||||
sudo pacman -S python python-reportlab poppler libtiff ghostscript
|
||||
sudo pacman -S python python-reportlab python-pillow poppler libtiff ghostscript
|
||||
```
|
||||
|
||||
| Tool | Package (Arch) | Role |
|
||||
| ----------- | ------------------ | ----------------------- |
|
||||
| `python3` | `python` | Host language |
|
||||
| `reportlab` | `python-reportlab` | Draws `pdf/origin.pdf` |
|
||||
| `PIL` | `python-pillow` | Generates patterns |
|
||||
| `tiffcp` | `libtiff` | Packs TIFFs |
|
||||
| `gs` | `ghostscript` | Converts PDF → XPS/TIFF |
|
||||
|
||||
@@ -71,8 +94,8 @@ missing from `PATH`.
|
||||
From anywhere:
|
||||
|
||||
```bash
|
||||
python utils/gen_visual_regression_data/run.py
|
||||
python utils/gen-visual-regression-data/run.py
|
||||
```
|
||||
|
||||
Output goes straight into `test_data/visual_regression/`, overwriting any
|
||||
existing files.
|
||||
existing files.
|
||||
@@ -10,8 +10,10 @@ import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
from reportlab.lib import colors
|
||||
from reportlab.lib.pagesizes import A4
|
||||
from reportlab.lib.utils import ImageReader
|
||||
from reportlab.pdfgen import canvas
|
||||
from reportlab.lib.units import mm
|
||||
|
||||
@@ -23,13 +25,16 @@ SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
REPO_ROOT = SCRIPT_DIR.parent.parent
|
||||
VR_DIR = REPO_ROOT / "test_data" / "visual_regression"
|
||||
|
||||
PAGE_SIZE = A4
|
||||
PAGE_W, PAGE_H = PAGE_SIZE
|
||||
|
||||
# Baseline rendering DPI.
|
||||
BASELINE_DPI = 300
|
||||
TIFF_DOWN_SCALE_FACTOR = 4
|
||||
|
||||
# Round A4 inward to whole baseline pixels (2480 x 3507). Fractional page
|
||||
# dimensions make renderers round/scale the page differently, shifting the
|
||||
# phase of the two-pixel patterns even when their detail is preserved.
|
||||
PAGE_SIZE = tuple(math.floor(side * BASELINE_DPI / 72) * 72 / BASELINE_DPI for side in A4)
|
||||
PAGE_W, PAGE_H = PAGE_SIZE
|
||||
|
||||
# Pin reportlab / Ghostscript output timestamps for byte-stable output.
|
||||
os.environ.setdefault("SOURCE_DATE_EPOCH", "1700000000")
|
||||
|
||||
@@ -316,6 +321,49 @@ def _page_gradient(c: canvas.Canvas) -> None:
|
||||
_draw_footer(c, 4)
|
||||
|
||||
|
||||
def _page_raster_detail(c: canvas.Canvas) -> None:
|
||||
"""Page 5: raster detail that is lost when PDF images render at 96 dpi."""
|
||||
_draw_page_header(c, 5, "Raster Detail (300 dpi)")
|
||||
|
||||
# Embed images, not vector strokes: Windows.Data.Pdf can preserve vectors
|
||||
# while downsampling images to its default 96 dpi. Two- and three-pixel
|
||||
# bands at 300 dpi become subpixel detail at 96 dpi.
|
||||
#
|
||||
# Fill the page body with a two-by-two grid, leaving room for the header,
|
||||
# labels, and footer. Derive pixel dimensions from the available space so
|
||||
# enlarging the blocks preserves their 300-dpi detail rather than stretching it.
|
||||
margin_x = 36
|
||||
gap_x = 18
|
||||
gap_y = 36
|
||||
top_y = PAGE_H - 108
|
||||
bottom_y = 54
|
||||
width_px = int((PAGE_W - 2 * margin_x - gap_x) / 2 * BASELINE_DPI / 72)
|
||||
height_px = int((top_y - bottom_y - gap_y) / 2 * BASELINE_DPI / 72)
|
||||
width_pt = width_px * 72 / BASELINE_DPI
|
||||
height_pt = height_px * 72 / BASELINE_DPI
|
||||
patterns = (
|
||||
("Vertical, 2 px", lambda x, y: x // 2),
|
||||
("Horizontal, 2 px", lambda x, y: y // 2),
|
||||
("Checkerboard, 3 px", lambda x, y: x // 3 + y // 3),
|
||||
("Diagonal, 3 px", lambda x, y: (x + y) // 3),
|
||||
)
|
||||
for i, (label, band) in enumerate(patterns):
|
||||
pixels = bytes(
|
||||
255 * (band(x, y) % 2)
|
||||
for y in range(height_px)
|
||||
for x in range(width_px)
|
||||
)
|
||||
img = Image.frombytes("L", (width_px, height_px), pixels)
|
||||
x = margin_x + (i % 2) * (width_pt + gap_x)
|
||||
top = top_y - (i // 2) * (height_pt + gap_y)
|
||||
c.setFillColor(colors.black)
|
||||
c.setFont("Helvetica", 10)
|
||||
c.drawString(x, top + 12, label)
|
||||
c.drawImage(ImageReader(img), x, top - height_pt, width_pt, height_pt)
|
||||
|
||||
_draw_footer(c, 5)
|
||||
|
||||
|
||||
def generate_pdf(out_path: Path) -> None:
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
c = canvas.Canvas(
|
||||
@@ -335,6 +383,8 @@ def generate_pdf(out_path: Path) -> None:
|
||||
c.showPage()
|
||||
_page_gradient(c)
|
||||
c.showPage()
|
||||
_page_raster_detail(c)
|
||||
c.showPage()
|
||||
|
||||
c.save()
|
||||
|
||||
@@ -387,6 +437,8 @@ def convert_pdf_to_xps(pdf_path: Path, out_path: Path) -> None:
|
||||
"-dSAFER",
|
||||
"-dQUIET",
|
||||
"-sDEVICE=xpswrite",
|
||||
# Avoid xpswrite's default 96-dpi layout shifting the fine patterns.
|
||||
f"-r{BASELINE_DPI}",
|
||||
f"-sOutputFile={out_path}",
|
||||
str(pdf_path),
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user