wps

PostScript for the Web
git clone https://logand.com/git/wps.git/
Log | Files | Refs | LICENSE

wps.wps (11758B)


      1 %%% WPS: PostScript and PDF interpreter for HTML 5 canvas
      2 %%% http://logand.com/sw/wps/index.html
      3 %%% (c) 2009, 2010, 2011 Tomas Hlavaty
      4 %%% Licensed under the GPLv3+ license.
      5 %%% http://www.fsf.org/licensing/licenses/gpl.html
      6 
      7 currentdict/systemdict currentdict put
      8 systemdict/{/mark cvx put
      9 systemdict/[/mark cvx put
     10 systemdict/]
     11 /counttomark cvx
     12 /array cvx
     13 /astore cvx
     14 /exch cvx
     15 /pop cvx
     16 5 array astore cvx put
     17 systemdict/}/] cvx/cvx cvx 2 array astore cvx put
     18 systemdict/def{currentdict 2 index 2 index put pop pop}put
     19 
     20 /maxlength 1000 def % TODO
     21 /.bdef{bind def}bind def
     22 /.xdef{exch def}.bdef
     23 /dup{0 index}.bdef
     24 /load{dup where pop exch get}.bdef
     25 /.ldef{load def}.bdef
     26 /if{{}ifelse}.bdef
     27 /cleartomark{array pop}.bdef
     28 /known{exch begin where{currentdict eq}{false}if end}.bdef
     29 /store{1 index where{3 1 roll put}{def}ifelse}.bdef
     30 /not{{false}{true}ifelse}.bdef
     31 /.logand{{{true}{false}ifelse}{pop false}ifelse}.bdef
     32 /and/.logand .ldef % TODO numeric and
     33 /.logor{{pop true}{{true}{false}ifelse}ifelse}.bdef
     34 /or/.logor .ldef % TODO numeric or
     35 /ne{eq not}.bdef
     36 /ge{lt not}.bdef
     37 /le{1 index 1 index eq 3 1 roll lt or}.bdef
     38 /gt{le not}.bdef
     39 /.repeat{1 1 4 2 roll for}.bdef
     40 
     41 %% math
     42 
     43 /floor{.math(floor)1 .call}.bdef
     44 
     45 /neg{0 exch sub}.bdef
     46 /add{neg sub}.bdef
     47 /idiv{div floor}.bdef
     48 
     49 /abs{.math(abs)1 .call}.bdef
     50 /.acos{.math(acos)1 .call}.bdef
     51 /.asin{.math(asin)1 .call}.bdef
     52 /atan{exch .math(atan)1 .call}.bdef
     53 /.atan2{.math(atan2)2 .call}.bdef
     54 /ceiling{.math(ceil)1 .call}.bdef
     55 /cos{.math(cos)1 .call}.bdef
     56 /.exp{.math(exp)1 .call}.bdef
     57 /log{.math(log)1 .call}.bdef
     58 /.max{.math(max)2 .call}.bdef
     59 /.min{.math(min)2 .call}.bdef
     60 /.pow{.math(pow)2 .call}.bdef
     61 /.random{.math(random)0 .call}.bdef
     62 /rand{.random}.bdef % TODO follow spec
     63 /round{.math(round)1 .call}.bdef
     64 /sin{.math(sin)1 .call}.bdef
     65 /sqrt{.math(sqrt)1 .call}.bdef
     66 /.tan{.math(tan)1 .call}.bdef
     67 /truncate{.math(truncate)1 .call}.bdef % TODO Math.truncate does not exist!
     68 
     69 /.e{.math(E)get}.bdef
     70 /.ln2{.math(LN2)get}.bdef
     71 /.ln10{.math(LN10)get}.bdef
     72 /.log2e{.math(LOG2E)get}.bdef
     73 /.log10e{.math(LOG10E)get}.bdef
     74 /.pi{.math(PI)get}.bdef
     75 /.sqrt1_2{.math(SQRT1_2)get}.bdef
     76 /.sqrt2{.math(SQRT2)get}.bdef
     77 
     78 /cvr{1.0 mul}.bdef
     79 /cvi{round}.bdef
     80 
     81 %% html
     82 
     83 /.setTimeout{.window(setTimeout)2 .call}.bdef % cb ms -- id
     84 /.clearTimeout{.window(clearTimeout)1 .call pop}.bdef % id --
     85 /.setInterval{.window(setInterval)2 .call}.bdef % cb ms -- id
     86 /.clearInterval{.window(clearInterval)1 .call pop}.bdef % id --
     87 /.document{.window(document)get}.bdef % -- document
     88 /.getElementById{.document(getElementById)1 .call}.bdef % id -- w
     89 /.hook{put}.bdef % e k cb --
     90 
     91 %% canvas
     92 
     93 /.setGc{.getElementById(2d)exch(getContext)1 .call/.$gc .xdef}.bdef
     94 /.gc{/.$gc load}.bdef
     95 /.gget{.gc exch get}.bdef
     96 /.gput{.gc 3 1 roll exch put}.bdef
     97 /.gcall0{.gc 3 1 roll .call pop}.bdef
     98 /.gcall1{.gc 3 1 roll .call}.bdef
     99 /.gcanvas{(canvas).gget}.bdef
    100 /.gdim{.gcanvas exch(height)exch put .gcanvas exch(width)exch put}.bdef
    101 /.gbox{.gdim pop pop}.bdef % TODO compute properly
    102 
    103 /.save{(save)0 .gcall0}.bdef
    104 /.restore{(restore)0 .gcall0}.bdef
    105 /.scale{(scale)2 .gcall0}.bdef
    106 /.rotate{(rotate)1 .gcall0}.bdef
    107 /.translate{(translate)2 .gcall0}.bdef
    108 /.transform{(transform)6 .gcall0}.bdef
    109 /.setTransform{(setTransform)6 .gcall0}.bdef
    110 /.createLinearGradient{(createLinearGradient)4 .gcall1}.bdef
    111 /.createRadialGradient{(createRadialGradient)6 .gcall1}.bdef
    112 /.createPattern{(createPattern)2 .gcall1}.bdef
    113 /.clearRect{(clearRect)4 .gcall0}.bdef
    114 /.fillRect{(fillRect)4 .gcall0}.bdef
    115 /.strokeRect{(strokeRect)4 .gcall0}.bdef
    116 /.beginPath{(beginPath)0 .gcall0}.bdef
    117 /.closePath{(closePath)0 .gcall0}.bdef
    118 /.moveTo{(moveTo)2 .gcall0}.bdef
    119 /.lineTo{(lineTo)2 .gcall0}.bdef
    120 /.quadraticCurveTo{(quadraticCurveTo)4 .gcall0}.bdef
    121 /.bezierCurveTo{(bezierCurveTo)6 .gcall0}.bdef
    122 /.arcTo{(arcTo)5 .gcall0}.bdef
    123 /.rect{(rect)4 .gcall0}.bdef
    124 /.arc{(arc)6 .gcall0}.bdef
    125 /.fill{(fill)0 .gcall0}.bdef
    126 /.stroke{(stroke)0 .gcall0}.bdef
    127 /.clip{(clip)0 .gcall0}.bdef
    128 /.isPointInPath{(isPointInPath)2 .gcall1}.bdef
    129 /.fillText{(fillText)4 .gcall0}.bdef
    130 /.fillText{}.bdef % TODO not working in Firefox
    131 /.strokeText{(strokeText)4 .gcall0}.bdef
    132 /.strokeText{}.bdef % TODO not working in Firefox
    133 /.measureText{(measureText)1 .gcall1}.bdef
    134 /.drawImage1{(drawImage1)5 .gcall0}.bdef
    135 /.drawImage2{(drawImage2)9 .gcall0}.bdef
    136 /.createImageData1{(createImageData1)1 .gcall1}.bdef
    137 /.createImageData2{(createImageData2)2 .gcall1}.bdef
    138 /.getImageData{(getImageData)4 .gcall1}.bdef
    139 /.putImageData{(putImageData)7 .gcall0}.bdef
    140 
    141 /.getGlobalAlpha{(globalAlpha).gget}.bdef
    142 /.getGlobalCompositeOperation{(globalCompositeOperation).gget}.bdef
    143 /.getStrokeStyle{(strokeStyle).gget}.bdef
    144 /.getFillStyle{(fillStyle).gget}.bdef
    145 /.getLineWidth{(lineWidth).gget}.bdef
    146 /.getLineCap{(lineCap).gget}.bdef
    147 /.getLineJoin{(lineJoin).gget}.bdef
    148 /.getMiterLimit{(miterLimit).gget}.bdef
    149 /.getShadowOffsetX{(shadowOffsetX).gget}.bdef
    150 /.getShadowOffsetY{(shadowOffsetY).gget}.bdef
    151 /.getShadowBlur{(shadowBlur).gget}.bdef
    152 /.getShadowColor{(shadowColor).gget}.bdef
    153 /.getFont{(font).gget}.bdef
    154 /.getTextAlign{(textAlign).gget}.bdef
    155 /.getTextBaseline{(textBaseline).gget}.bdef
    156 
    157 /.setGlobalAlpha{(globalAlpha).gput}.bdef
    158 /.setGlobalCompositeOperation{(globalCompositeOperation).gput}.bdef
    159 /.setStrokeStyle{(strokeStyle).gput}.bdef
    160 /.setFillStyle{(fillStyle).gput}.bdef
    161 /.setLineWidth{(lineWidth).gput}.bdef
    162 /.setLineCap{(lineCap).gput}.bdef
    163 /.setLineJoin{(lineJoin).gput}.bdef
    164 /.setLineCap{pop}.bdef % TODO remove this later (Firefox throws)
    165 /.setLineJoin{pop}.bdef % TODO remove this later (Firefox throws)
    166 /.setMiterLimit{(miterLimit).gput}.bdef
    167 /.setShadowOffsetX{(shadowOffsetX).gput}.bdef
    168 /.setShadowOffsetY{(shadowOffsetY).gput}.bdef
    169 /.setShadowBlur{(shadowBlur).gput}.bdef
    170 /.setShadowColor{(shadowColor).gput}.bdef
    171 /.setFont{(font).gput}.bdef
    172 /.setTextAlign{(textAlign).gput}.bdef
    173 /.setTextBaseline{(textBaseline).gput}.bdef
    174 
    175 %% PostScript
    176 
    177 /.deg2rad{.pi 180 div mul}.bdef
    178 /.rad2deg{180 .pi div mul}.bdef
    179 
    180 /.$cx 0 def
    181 /.$cy 0 def
    182 /.$px 0 def
    183 /.$py 0 def
    184 /.setPoint{/.$cy .xdef/.$cx .xdef}.bdef
    185 /.setPath{/.$py .xdef/.$px .xdef}.bdef
    186 /currentpoint{/.$cx load /.$cy load}.bdef
    187 /.getPath{/.$px load /.$py load}.bdef
    188 
    189 /identmatrix{pop [1 0 0 1 0 0]}.bdef % TODO fill
    190 /matrix{6 array identmatrix}.bdef
    191 /setmatrix{/.$tm .xdef}.bdef
    192 /defaultmatrix{pop matrix}.bdef % TODO fill
    193 /initmatrix{matrix defaultmatrix setmatrix}.bdef
    194 /currentmatrix{pop /.$tm load}.bdef % TODO fill
    195 initmatrix
    196 
    197 /.getTmd{/.$tmd load}.bdef
    198 /.setTmd{/.$tmd .xdef}.bdef
    199 /.resetTmd{matrix .setTmd}.bdef
    200 .resetTmd
    201 
    202 /.update{ % m --
    203   currentpoint 2 index % m .$cx .$cy m
    204   .xy .setPoint % m
    205   dup .getTmd exch .mmul .setTmd % (.$tmd x m)
    206   dup currentmatrix exch .mmul setmatrix % = .$tm x m
    207 }.bdef
    208 
    209 /transform{dup type(arraytype)ne{.getTmd}if .xy}.bdef
    210 /itransform{dup type(arraytype)ne{.getTmd}if .minv .xy}.bdef
    211 
    212 /.scaleM{0 0 3 2 roll 0 0 6 array astore}.bdef % x y -- [x 0 0 y 0 0]
    213 /.scale3{pop .scaleM}.bdef
    214 /.scale2{2 copy .scaleM .update .scale}.bdef
    215 /scale{dup type(arraytype)eq{.scale3}{.scale2}ifelse}.bdef
    216 
    217 /.translateM{1 0 0 1 6 4 roll 6 array astore}.bdef % x y -- [1 0 0 1 x y]
    218 /.translate3{pop .translateM}.bdef
    219 /.translate2{2 copy .translateM .update .translate}.bdef
    220 /translate{dup type(arraytype)eq{.translate3}{.translate2}ifelse}.bdef
    221 
    222 /.rotateM{dup cos exch sin dup neg 2 index 0 0 6 array astore}.bdef % a -- [c s -s c 0 0]
    223 /.rotate2{pop .deg2rad .rotateM}.bdef
    224 /.rotate1{.deg2rad dup .rotateM .update .rotate}.bdef
    225 /rotate{dup type(arraytype)eq{.rotate2}{.rotate1}ifelse}.bdef
    226 
    227 %matrix concat – 	Replace CTM by matrix ´ CTM
    228 %matrix1 matrix2 matrix3 concatmatrix matrix3 	Fill matrix3 with matrix1 ´ matrix2
    229 
    230 %dx dy dtransform dx¢ dy¢ 	Transform distance (dx, dy) by CTM
    231 %dx dy matrix dtransform dx¢ dy¢ 	Transform distance (dx, dy) by matrix
    232 
    233 %dx¢ dy¢ idtransform dx dy 	Perform inverse transform of distance (dx¢, dy¢) by CTM
    234 %dx¢ dy¢ matrix idtransform dx dy 	Perform inverse transform of distance (dx¢, dy¢) by matrix
    235 
    236 %matrix1 matrix2 invertmatrix matrix2 	Fill matrix2 with inverse of matrix1
    237 
    238 /gsave{.save}.bdef
    239 /grestore{.restore}.bdef
    240 /clip{.clip}.bdef
    241 /rectclip{.clearRect}.bdef
    242 /rectfill{.fillRect}.bdef
    243 /rectstroke{.strokeRect}.bdef
    244 /newpath{.beginPath}.bdef
    245 /closepath{.closePath}.bdef
    246 /moveto{2 copy .setPoint 2 copy .setPath .resetTmd .moveTo}.bdef
    247 /lineto{2 copy .setPoint 2 copy .setPath .resetTmd .lineTo}.bdef
    248 /arcto{.arcTo}.bdef
    249 
    250 /setlinewidth{.setLineWidth}.bdef
    251 /setlinecap{.setLineCap}.bdef % TODO
    252 /setlinejoin{.setLineJoin}.bdef % TODO
    253 /setmiterlimit{.setMiterLimit}.bdef
    254 
    255 /currentlinewidth{.getLineWidth}.bdef
    256 /currentlinecap{<</butt 0/round 1/square 2>> .getLineCap get}.bdef
    257 /currentlinejoin{<</miter 0/round 1/bevel 2>> .getLineJoin get}.bdef
    258 /currentmiterlimit{.getMiterLimit}.bdef
    259 
    260 /setgray{255 mul dup dup .rgb dup .setStrokeStyle .setFillStyle}.bdef
    261 /setrgbcolor{3{255 mul round 3 1 roll}repeat .rgb dup .setStrokeStyle .setFillStyle}.bdef
    262 /setcmykcolor{setrgbcolor pop}.bdef % TODO
    263 /sethsbcolor{setrgbcolor}.bdef % TODO
    264 /clippath{0 0 .gcanvas(width)get .gcanvas(height)get .rect}.bdef % TODO
    265 /show{currentpoint 3 2 roll 3 copy .fillText .strokeText}.bdef % TODO
    266 
    267 /rlineto{.getTmd .xy /.$py load add exch /.$px load add exch .getTmd .minv .xy lineto}.bdef
    268 /curveto{2 copy .setPoint 2 copy .setPath .resetTmd .bezierCurveTo}.bdef
    269 
    270 /currentflat{42}.bdef % TODO
    271 /setflat{pop}.bdef % TODO
    272 
    273 /arc{.deg2rad exch .deg2rad exch true .arc}.bdef % TODO currentpoint
    274 /arcn{.deg2rad exch .deg2rad exch false .arc}.bdef % TODO currentpoint
    275 
    276 /fill{.fill newpath currentpoint .moveTo}.bdef % TODO
    277 
    278 /setdash{pop pop}.bdef % TODO
    279 
    280 /stroke{.stroke newpath currentpoint .moveTo}.bdef
    281 
    282 /showpage{}.bdef % TODO
    283 /grestoreall{}.bdef % TODO
    284 /readonly{}.bdef % TODO
    285 /currentfile{(url?)}.bdef % TODO
    286 /eexec{pop}.bdef % TODO
    287 /findfont{}.bdef % TODO
    288 /scalefont{pop}.bdef % TODO
    289 /setfont{pop}.bdef % TODO C.font = N + "pt " + F.V;
    290 /stopped{}.bdef % TODO
    291 /loop{}.bdef % TODO !!!
    292 /string{}.bdef % TODO
    293 /pathbbox{}.bdef % TODO
    294 /urx{}.bdef % TODO
    295 /ury{}.bdef % TODO
    296 /llx{}.bdef % TODO
    297 /lly{}.bdef % TODO
    298 /pagewidth{}.bdef % TODO
    299 /pageheight{}.bdef % TODO
    300 /inwidth{}.bdef % TODO
    301 /inheight{}.bdef % TODO
    302 /usertime{}.bdef % TODO
    303 /srand{}.bdef % TODO
    304 
    305 %% PDF
    306 
    307 /w{setlinewidth}.bdef
    308 /J{setlinecap}.bdef % TODO
    309 /j{setlinejoin}.bdef % TODO
    310 /M{setmiterlimit}.bdef
    311 /d{setdash}.bdef % TODO
    312 /ri{}.bdef % TODO
    313 /i{1 .min setflat}.bdef
    314 /gs{}.bdef % TODO
    315 /q{gsave}.bdef
    316 /Q{grestore}.bdef
    317 /cm{.transform}.bdef
    318 /m{newpath moveto}.bdef % TODO only if not m previously
    319 /l{lineto}.bdef
    320 /c{.bezierCurveTo}.bdef
    321 /v{currentpoint 6 2 roll c}.bdef
    322 /y{2 copy c}.bdef
    323 /h{closepath}.bdef % TODO
    324 /re{.rect}.bdef % TODO really, or x y m , x+w y l , x+w y+h l , x y+h l , h
    325 /S{stroke}.bdef
    326 /s{h S}.bdef
    327 /f{fill}.bdef % TODO
    328 /F{f}.bdef
    329 /f*{}.bdef % TODO
    330 /B{f S}.bdef
    331 /B*{f* S}.bdef
    332 /b{h B}.bdef
    333 /b*{h B*}.bdef
    334 /n{}.bdef % TODO
    335 /W{clip}.bdef % TODO
    336 /W*{clip}.bdef % TODO
    337 /BT{}.bdef % TODO
    338 /ET{}.bdef % TODO
    339 /Tc{}.bdef % TODO
    340 /Tw{}.bdef % TODO
    341 /Tz{}.bdef % TODO
    342 /TL{}.bdef % TODO
    343 /Tf{setfont}.bdef % TODO
    344 /Tr{}.bdef % TODO
    345 /Ts{}.bdef % TODO
    346 /Td{translate 0 0 moveto}.bdef
    347 /TD{}.bdef % TODO
    348 /Tm{}.bdef % TODO
    349 /T*{}.bdef % TODO
    350 /Tj{show}.bdef % TODO
    351 /TJ{}.bdef % TODO
    352 /'{}.bdef % TODO
    353 /"{}.bdef % TODO
    354 /d0{}.bdef % TODO
    355 /d1{}.bdef % TODO
    356 /CS{}.bdef % TODO
    357 /cs{}.bdef % TODO
    358 %/SC/setcolor .ldef
    359 /SCN{}.bdef % TODO
    360 %/sc/setcolor .ldef
    361 /scn{}.bdef % TODO
    362 /G{}.bdef % TODO
    363 /g{}.bdef % TODO
    364 /RG{}.bdef % TODO
    365 /rg{setrgbcolor}.bdef % TODO
    366 /K{}.bdef % TODO
    367 /k{}.bdef % TODO
    368 /sh{}.bdef % TODO
    369 /BI{}.bdef % TODO
    370 /ID{}.bdef % TODO
    371 /EI{}.bdef % TODO
    372 /Do{}.bdef % TODO
    373 /MP{}.bdef % TODO
    374 /DP{}.bdef % TODO
    375 /BMC{}.bdef % TODO
    376 /BDC{}.bdef % TODO
    377 /EMC{}.bdef % TODO
    378 /BX{}.bdef % TODO
    379 /EX{}.bdef % TODO
    380 
    381 %% finish
    382 
    383 false .strictBind
    384 
    385 /userdict 1000 dict def
    386 userdict begin