/pliant/graphic/vector/font.pli
 
 1  abstract 
 2    [Loading and rendering a PostScript Type 1 font] 
 3   
 4  # Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx 
 5  # Fixed by  Patrice Ossona de Mendez 
 6   
 7  # ttf2pt1 -b /tmp/foo.ttf /tmp/foo 
 8  # http://dustismo.com/ 
 9   
 10  module "/pliant/language/compiler.pli" 
 11  module "/pliant/language/stream.pli" 
 12  module "/pliant/language/stream/filesystembase.pli" 
 13  module "/pliant/language/stream/multi.pli" 
 14  module "/pliant/math/point.pli" 
 15  module "/pliant/math/vector.pli" 
 16  module "/pliant/math/curve.pli" 
 17  module "/pliant/math/transform.pli" 
 18  module "/pliant/language/type/text/str32.pli" 
 19  module "/pliant/graphic/misc/int.pli" 
 20  module "/pliant/graphic/misc/float.pli" 
 21  module "/pliant/language/data/cache.pli" 
 22  module "/pliant/language/compiler/type/inherit.pli" 
 23  module "/pliant/language/data/cache.pli" 
 24  module "/pliant/admin/md5.pli" 
 25   
 26  constant raster_fonts true 
 27  constant raster_maximum_size 63 
 28  constant raster_anti_aliasing 4 
 29  constant auto_accent true 
 30  constant type1details false 
 31  constant verbose false 
 32   
 33   
 34 
 
 35  # Goodies 
 36   
 37   
 38  function '+' p v -> r 
 39    arg Point2 p ; arg Vector2 v ; arg Point2 r 
 40    := p:x+v:x 
 41    := p:y+v:y 
 42   
 43  function '+' v1 v2 -> r 
 44    arg Vector2 v1 v2 r 
 45    := v1:x+v2:x 
 46    := v1:y+v2:y 
 47   
 48  function '*' f v -> r 
 49    arg Float f ; arg Vector2 r 
 50    := f*v:x 
 51    := f*v:y 
 52   
 53  method v length -> w 
 54    arg Vector2 v ; arg Float w 
 55    if v:y=0 
 56      := x 
 57    else 
 58      := (v:x*v:x+v:y*v:y)^0.5 
 59   
 60   
 61 
 
 62  # Decoding .pfb files 
 63   
 64   
 65  type PfbStreamDriver 
 66    field Link:Stream src ; field CBool eof 
 67    field uInt16 er cr 
 68    field Int lenIV enb cnb 
 69    field CBool first 
 70    field Address buffer ; field Int buflen 
 71  StreamDriver maybe PfbStreamDriver 
 72   
 73   
 74  type PfbFileSystem 
 75    void 
 76  FileSystem maybe PfbFileSystem 
 77   
 78   
 79  method fs open name options flags stream support -> status 
 80    oarg_rw PfbFileSystem fs ; arg Str name options ; arg Int flags ; arg_rw Stream stream support ; arg ExtendedStatus status 
 81    var Link:Stream s 
 82    if exists:support 
 83      :> support 
 84    else 
 85      :> new Stream 
 86      open name options (flags .and. in+out+append+safe) 
 87      if s=failure 
 88        return failure 
 89    var Link:PfbStreamDriver drv :> new PfbStreamDriver 
 90    drv src :> s ; drv eof := false 
 91    drv er := 55665 
 92    drv lenIV := 4 
 93    drv enb := 0 ; drv cnb := 0 
 94    drv first := true 
 95    drv buffer := memory_allocate 2^16 addressof:drv ; drv buflen := 0 
 96    stream stream_driver :> drv 
 97    status := success 
 98   
 99   
 100  method drv edecrypt cipher -> plain 
 101    arg_rw PfbStreamDriver drv ; arg Int cipher plain 
 102    implicit drv 
 103      plain := cipher .xor. (er 2^8) 
 104      er := ( ((cast cipher uInt) er) 52845 22719 ) .and. 2^16-1 
 105   
 106  method drv cdecrypt cipher -> plain 
 107    arg_rw PfbStreamDriver drv ; arg Int cipher plain 
 108    implicit drv 
 109      plain := cipher .xor. (cr 2^8) 
 110      cr := ( ((cast cipher uInt) cr) 52845 22719 ) .and. 2^16-1 
 111   
 112   
 113  method drv egetc -> c 
 114    arg_rw PfbStreamDriver drv ; arg Int c 
 115    drv:src raw_read addressof:(var uInt8 cipher) 1 
 116    drv enb -= 1 
 117    := drv edecrypt cipher 
 118   
 119  method drv cgetc -> c 
 120    arg_rw PfbStreamDriver drv ; arg Int c 
 121    drv:src raw_read addressof:(var uInt8 cipher) 1 
 122    drv enb -= 1 ; drv cnb -= 1 
 123    := drv cdecrypt (drv edecrypt cipher) 
 124   
 125   
 126  method drv output c 
 127    arg_rw PfbStreamDriver drv ; arg Int c 
 128    drv:buffer map uInt8 drv:buflen := c 
 129    drv buflen += 1 
 130   
 131  method drv atoken 
 132    arg_rw PfbStreamDriver drv 
 133    drv:src raw_read addressof:(var uInt8 c) 1 
 134    if c=80h 
 135      drv:src raw_read addressof:(var uInt8 mode) 1 
 136      if mode=01h 
 137        drv:src raw_read addressof:(var uInt32 u) uInt32:size 
 138      eif mode=02h 
 139        drv:src raw_read addressof:(var uInt32 u) uInt32:size 
 140        drv enb := u 
 141        if drv:first 
 142          for (var Int i) 0 3 
 143            drv egetc 
 144          drv first := false 
 145      eif mode=03h 
 146        drv eof := true 
 147    else 
 148      drv output c 
 149   
 150  method drv etoken 
 151    arg_rw PfbStreamDriver drv 
 152    drv output drv:egetc 
 153   
 154  method drv output string 
 155    arg_rw PfbStreamDriver drv ; arg Str string 
 156    drv output " ":number 
 157    for (var Int i) string:len-1 
 158      drv output string:i:number 
 159   
 160  method drv ctoken 
 161    arg_rw PfbStreamDriver drv 
 162    var Int := drv cgetc 
 163    if b>=32 
 164      var Int val 
 165      if b<=246 
 166        val := 139 
 167      eif b<=250 
 168        val := (247)*256 108 drv:cgetc 
 169      eif b<=254 
 170        val := -(251)*256 108 drv:cgetc 
 171      else 
 172        val := 0 
 173        for (var Int i) 0 3 
 174          addressof:val map uInt8 3-:= drv cgetc 
 175      drv output string:val 
 176    else 
 177      if b=1 
 178        drv output "hstem" 
 179      eif b=3 
 180        drv output "vstem" 
 181      eif b=4 
 182        drv output "vmoveto" 
 183      eif b=5 
 184        drv output "rlineto" 
 185      eif b=6 
 186        drv output "hlineto" 
 187      eif b=7 
 188        drv output "vlineto" 
 189      eif b=8 
 190        drv output "rrcurveto" 
 191      eif b=9 
 192        drv output "closepath" 
 193      eif b=10 
 194        drv output "callsubr" 
 195      eif b=11 
 196        drv output "return" 
 197      eif b=13 
 198        drv output "hsbw" 
 199      eif b=14 
 200        drv output "endchar" 
 201      eif b=21 
 202        drv output "rmoveto" 
 203      eif b=22 
 204        drv output "hmoveto" 
 205      eif b=30 
 206        drv output "vhcurveto" 
 207      eif b=31 
 208        drv output "hvcurveto" 
 209      eif b=12 
 210        := drv cgetc 
 211        if b=0 
 212          drv output "dotsection" 
 213        eif b=1 
 214          drv output "vstem3" 
 215        eif b=2 
 216          drv output "hstem3" 
 217        eif b=6 
 218          drv output "seac" 
 219        eif b=7 
 220          drv output "sbw" 
 221        eif b=12 
 222          drv output "div" 
 223        eif b=16 
 224          drv output "callothersubr" 
 225        eif b=17 
 226          drv output "pop" 
 227        eif b=33 
 228          drv output "setcurrentpoint" 
 229    if drv:cnb=0 
 230      drv output " ":number 
 231      drv output "}":number 
 232       
 233   
 234  method drv read adr mini maxi -> red 
 235    oarg_rw PfbStreamDriver drv ; arg Address adr ; arg Int mini maxi red 
 236    implicit drv 
 237      while not src:atend and not eof and (buflen=or buflen<mini or { var Int := buffer map uInt8 buflen-1 ; c<>0Dh and c<>0Ah }) 
 238        if cnb<>and enb<>0 
 239          ctoken 
 240        eif enb<>0 
 241          etoken 
 242        else 
 243          atoken 
 244        if buflen>=4 
 245          (var Str s) set (buffer translate Byte buflen-4) 4 false 
 246          if s=" -| " or s=" RD " 
 247            var Int := buflen-5 
 248            while i>and { var Int := buffer map uInt8 i ; c>="0":number and c<="9":number } 
 249              -= 1 
 250            set (buffer translate Byte i) buflen-i-false 
 251            parse cnb 
 252            buflen := i ; output "{" 
 253            cr := 4330 
 254            for (var Int i) lenIV-1 
 255              cgetc 
 256      if buflen>and { var Int := buffer map uInt8 buflen-1 ; c=0Ah or c=0Dh } 
 257        buffer map uInt8 buflen-:= 0Dh 
 258        buffer map uInt8 buflen := 0Ah 
 259        buflen += 1 
 260      set buffer buflen false 
 261      if (parse "/lenIV" (var Int n) any) 
 262        lenIV := n 
 263      red := min buflen maxi 
 264      memory_copy buffer adr red 
 265      buflen -= red 
 266      memory_move (buffer translate Byte red) buffer buflen 
 267      
 268               
 269  method drv close -> status 
 270    oarg_rw PfbStreamDriver drv ; arg ExtendedStatus status 
 271    memory_free drv:buffer 
 272    status := success 
 273   
 274  gvar PfbFileSystem pfb_file_system 
 275  pliant_multi_file_system mount "pfb:" "" pfb_file_system 
 276   
 277   
 278 
 
 279  # Loading a PostScript Type 1 font 
 280   
 281   
 282  gvar (Dictionary Str Int) postscript_glyphs 
 283   
 284  function glyph name uv 
 285    arg Str name ; arg Int uv 
 286    postscript_glyphs insert name uv 
 287   
 288  glyph "A" 65 
 289  glyph "AE" 198 
 290  glyph "AEacute" 508 
 291  glyph "AEsmall" 63462 
 292  glyph "Aacute" 193 
 293  glyph "Aacutesmall" 63457 
 294  glyph "Abreve" 258 
 295  glyph "Acircumflex" 194 
 296  glyph "Acircumflexsmall" 63458 
 297  glyph "Acute" 63177 
 298  glyph "Acutesmall" 63412 
 299  glyph "Adieresis" 196 
 300  glyph "Adieresissmall" 63460 
 301  glyph "Agrave" 192 
 302  glyph "Agravesmall" 63456 
 303  glyph "Alpha" 913 
 304  glyph "Alphatonos" 902 
 305  glyph "Amacron" 256 
 306  glyph "Aogonek" 260 
 307  glyph "Aring" 197 
 308  glyph "Aringacute" 506 
 309  glyph "Aringsmall" 63461 
 310  glyph "Asmall" 63329 
 311  glyph "Atilde" 195 
 312  glyph "Atildesmall" 63459 
 313  glyph "B" 66 
 314  glyph "Beta" 914 
 315  glyph "Brevesmall" 63220 
 316  glyph "Bsmall" 63330 
 317  glyph "C" 67 
 318  glyph "Cacute" 262 
 319  glyph "Caron" 63178 
 320  glyph "Caronsmall" 63221 
 321  glyph "Ccaron" 268 
 322  glyph "Ccedilla" 199 
 323  glyph "Ccedillasmall" 63463 
 324  glyph "Ccircumflex" 264 
 325  glyph "Cdotaccent" 266 
 326  glyph "Cedillasmall" 63416 
 327  glyph "Chi" 935 
 328  glyph "Circumflexsmall" 63222 
 329  glyph "Csmall" 63331 
 330  glyph "D" 68 
 331  glyph "Dcaron" 270 
 332  glyph "Dcroat" 272 
 333  glyph "Delta" 8710 
 334  glyph "Delta" 916 
 335  glyph "Dieresis" 63179 
 336  glyph "DieresisAcute" 63180 
 337  glyph "DieresisGrave" 63181 
 338  glyph "Dieresissmall" 63400 
 339  glyph "Dotaccentsmall" 63223 
 340  glyph "Dsmall" 63332 
 341  glyph "E" 69 
 342  glyph "Eacute" 201 
 343  glyph "Eacutesmall" 63465 
 344  glyph "Ebreve" 276 
 345  glyph "Ecaron" 282 
 346  glyph "Ecircumflex" 202 
 347  glyph "Ecircumflexsmall" 63466 
 348  glyph "Edieresis" 203 
 349  glyph "Edieresissmall" 63467 
 350  glyph "Edotaccent" 278 
 351  glyph "Egrave" 200 
 352  glyph "Egravesmall" 63464 
 353  glyph "Emacron" 274 
 354  glyph "Eng" 330 
 355  glyph "Eogonek" 280 
 356  glyph "Epsilon" 917 
 357  glyph "Epsilontonos" 904 
 358  glyph "Esmall" 63333 
 359  glyph "Eta" 919 
 360  glyph "Etatonos" 905 
 361  glyph "Eth" 208 
 362  glyph "Ethsmall" 63472 
 363  glyph "Euro" 8364 
 364  glyph "F" 70 
 365  glyph "Fsmall" 63334 
 366  glyph "G" 71 
 367  glyph "Gamma" 915 
 368  glyph "Gbreve" 286 
 369  glyph "Gcaron" 486 
 370  glyph "Gcircumflex" 284 
 371  glyph "Gcommaaccent" 290 
 372  glyph "Gdotaccent" 288 
 373  glyph "Grave" 63182 
 374  glyph "Gravesmall" 63328 
 375  glyph "Gsmall" 63335 
 376  glyph "H" 72 
 377  glyph "H18533" 9679 
 378  glyph "H18543" 9642 
 379  glyph "H18551" 9643 
 380  glyph "H22073" 9633 
 381  glyph "Hbar" 294 
 382  glyph "Hcircumflex" 292 
 383  glyph "Hsmall" 63336 
 384  glyph "Hungarumlaut" 63183 
 385  glyph "Hungarumlautsmall" 63224 
 386  glyph "I" 73 
 387  glyph "IJ" 306 
 388  glyph "Iacute" 205 
 389  glyph "Iacutesmall" 63469 
 390  glyph "Ibreve" 300 
 391  glyph "Icircumflex" 206 
 392  glyph "Icircumflexsmall" 63470 
 393  glyph "Idieresis" 207 
 394  glyph "Idieresissmall" 63471 
 395  glyph "Idotaccent" 304 
 396  glyph "Ifraktur" 8465 
 397  glyph "Igrave" 204 
 398  glyph "Igravesmall" 63468 
 399  glyph "Imacron" 298 
 400  glyph "Iogonek" 302 
 401  glyph "Iota" 921 
 402  glyph "Iotadieresis" 938 
 403  glyph "Iotatonos" 906 
 404  glyph "Ismall" 63337 
 405  glyph "Itilde" 296 
 406  glyph "J" 74 
 407  glyph "Jcircumflex" 308 
 408  glyph "Jsmall" 63338 
 409  glyph "K" 75 
 410  glyph "Kappa" 922 
 411  glyph "Kcommaaccent" 310 
 412  glyph "Ksmall" 63339 
 413  glyph "L" 76 
 414  glyph "LL" 63167 
 415  glyph "Lacute" 313 
 416  glyph "Lambda" 923 
 417  glyph "Lcaron" 317 
 418  glyph "Lcommaaccent" 315 
 419  glyph "Ldot" 319 
 420  glyph "Lslash" 321 
 421  glyph "Lslashsmall" 63225 
 422  glyph "Lsmall" 63340 
 423  glyph "M" 77 
 424  glyph "Macron" 63184 
 425  glyph "Macronsmall" 63407 
 426  glyph "Msmall" 63341 
 427  glyph "Mu" 924 
 428  glyph "N" 78 
 429  glyph "Nacute" 323 
 430  glyph "Ncaron" 327 
 431  glyph "Ncommaaccent" 325 
 432  glyph "Nsmall" 63342 
 433  glyph "Ntilde" 209 
 434  glyph "Ntildesmall" 63473 
 435  glyph "Nu" 925 
 436  glyph "O" 79 
 437  glyph "OE" 338 
 438  glyph "OEsmall" 63226 
 439  glyph "Oacute" 211 
 440  glyph "Oacutesmall" 63475 
 441  glyph "Obreve" 334 
 442  glyph "Ocircumflex" 212 
 443  glyph "Ocircumflexsmall" 63476 
 444  glyph "Odieresis" 214 
 445  glyph "Odieresissmall" 63478 
 446  glyph "Ogoneksmall" 63227 
 447  glyph "Ograve" 210 
 448  glyph "Ogravesmall" 63474 
 449  glyph "Ohorn" 416 
 450  glyph "Ohungarumlaut" 336 
 451  glyph "Omacron" 332 
 452  glyph "Omega" 8486 
 453  glyph "Omega" 937 
 454  glyph "Omegatonos" 911 
 455  glyph "Omicron" 927 
 456  glyph "Omicrontonos" 908 
 457  glyph "Oslash" 216 
 458  glyph "Oslashacute" 510 
 459  glyph "Oslashsmall" 63480 
 460  glyph "Osmall" 63343 
 461  glyph "Otilde" 213 
 462  glyph "Otildesmall" 63477 
 463  glyph "P" 80 
 464  glyph "Phi" 934 
 465  glyph "Pi" 928 
 466  glyph "Psi" 936 
 467  glyph "Psmall" 63344 
 468  glyph "Q" 81 
 469  glyph "Qsmall" 63345 
 470  glyph "R" 82 
 471  glyph "Racute" 340 
 472  glyph "Rcaron" 344 
 473  glyph "Rcommaaccent" 342 
 474  glyph "Rfraktur" 8476 
 475  glyph "Rho" 929 
 476  glyph "Ringsmall" 63228 
 477  glyph "Rsmall" 63346 
 478  glyph "S" 83 
 479  glyph "SF010000" 9484 
 480  glyph "SF020000" 9492 
 481  glyph "SF030000" 9488 
 482  glyph "SF040000" 9496 
 483  glyph "SF050000" 9532 
 484  glyph "SF060000" 9516 
 485  glyph "SF070000" 9524 
 486  glyph "SF080000" 9500 
 487  glyph "SF090000" 9508 
 488  glyph "SF100000" 9472 
 489  glyph "SF110000" 9474 
 490  glyph "SF190000" 9569 
 491  glyph "SF200000" 9570 
 492  glyph "SF210000" 9558 
 493  glyph "SF220000" 9557 
 494  glyph "SF230000" 9571 
 495  glyph "SF240000" 9553 
 496  glyph "SF250000" 9559 
 497  glyph "SF260000" 9565 
 498  glyph "SF270000" 9564 
 499  glyph "SF280000" 9563 
 500  glyph "SF360000" 9566 
 501  glyph "SF370000" 9567 
 502  glyph "SF380000" 9562 
 503  glyph "SF390000" 9556 
 504  glyph "SF400000" 9577 
 505  glyph "SF410000" 9574 
 506  glyph "SF420000" 9568 
 507  glyph "SF430000" 9552 
 508  glyph "SF440000" 9580 
 509  glyph "SF450000" 9575 
 510  glyph "SF460000" 9576 
 511  glyph "SF470000" 9572 
 512  glyph "SF480000" 9573 
 513  glyph "SF490000" 9561 
 514  glyph "SF500000" 9560 
 515  glyph "SF510000" 9554 
 516  glyph "SF520000" 9555 
 517  glyph "SF530000" 9579 
 518  glyph "SF540000" 9578 
 519  glyph "Sacute" 346 
 520  glyph "Scaron" 352 
 521  glyph "Scaronsmall" 63229 
 522  glyph "Scedilla" 350 
 523  glyph "Scedilla" 63169 
 524  glyph "Scircumflex" 348 
 525  glyph "Scommaaccent" 536 
 526  glyph "Sigma" 931 
 527  glyph "Ssmall" 63347 
 528  glyph "T" 84 
 529  glyph "Tau" 932 
 530  glyph "Tbar" 358 
 531  glyph "Tcaron" 356 
 532  glyph "Tcommaaccent" 354 
 533  glyph "Tcommaaccent" 538 
 534  glyph "Theta" 920 
 535  glyph "Thorn" 222 
 536  glyph "Thornsmall" 63486 
 537  glyph "Tildesmall" 63230 
 538  glyph "Tsmall" 63348 
 539  glyph "U" 85 
 540  glyph "Uacute" 218 
 541  glyph "Uacutesmall" 63482 
 542  glyph "Ubreve" 364 
 543  glyph "Ucircumflex" 219 
 544  glyph "Ucircumflexsmall" 63483 
 545  glyph "Udieresis" 220 
 546  glyph "Udieresissmall" 63484 
 547  glyph "Ugrave" 217 
 548  glyph "Ugravesmall" 63481 
 549  glyph "Uhorn" 431 
 550  glyph "Uhungarumlaut" 368 
 551  glyph "Umacron" 362 
 552  glyph "Uogonek" 370 
 553  glyph "Upsilon" 933 
 554  glyph "Upsilon1" 978 
 555  glyph "Upsilondieresis" 939 
 556  glyph "Upsilontonos" 910 
 557  glyph "Uring" 366 
 558  glyph "Usmall" 63349 
 559  glyph "Utilde" 360 
 560  glyph "V" 86 
 561  glyph "Vsmall" 63350 
 562  glyph "W" 87 
 563  glyph "Wacute" 7810 
 564  glyph "Wcircumflex" 372 
 565  glyph "Wdieresis" 7812 
 566  glyph "Wgrave" 7808 
 567  glyph "Wsmall" 63351 
 568  glyph "X" 88 
 569  glyph "Xi" 926 
 570  glyph "Xsmall" 63352 
 571  glyph "Y" 89 
 572  glyph "Yacute" 221 
 573  glyph "Yacutesmall" 63485 
 574  glyph "Ycircumflex" 374 
 575  glyph "Ydieresis" 376 
 576  glyph "Ydieresissmall" 63487 
 577  glyph "Ygrave" 7922 
 578  glyph "Ysmall" 63353 
 579  glyph "Z" 90 
 580  glyph "Zacute" 377 
 581  glyph "Zcaron" 381 
 582  glyph "Zcaronsmall" 63231 
 583  glyph "Zdotaccent" 379 
 584  glyph "Zeta" 918 
 585  glyph "Zsmall" 63354 
 586  glyph "a" 97 
 587  glyph "aacute" 225 
 588  glyph "abreve" 259 
 589  glyph "acircumflex" 226 
 590  glyph "acute" 180 
 591  glyph "acutecomb" 769 
 592  glyph "adieresis" 228 
 593  glyph "ae" 230 
 594  glyph "aeacute" 509 
 595  glyph "afii00208" 8213 
 596  glyph "afii10017" 1040 
 597  glyph "afii10018" 1041 
 598  glyph "afii10019" 1042 
 599  glyph "afii10020" 1043 
 600  glyph "afii10021" 1044 
 601  glyph "afii10022" 1045 
 602  glyph "afii10023" 1025 
 603  glyph "afii10024" 1046 
 604  glyph "afii10025" 1047 
 605  glyph "afii10026" 1048 
 606  glyph "afii10027" 1049 
 607  glyph "afii10028" 1050 
 608  glyph "afii10029" 1051 
 609  glyph "afii10030" 1052 
 610  glyph "afii10031" 1053 
 611  glyph "afii10032" 1054 
 612  glyph "afii10033" 1055 
 613  glyph "afii10034" 1056 
 614  glyph "afii10035" 1057 
 615  glyph "afii10036" 1058 
 616  glyph "afii10037" 1059 
 617  glyph "afii10038" 1060 
 618  glyph "afii10039" 1061 
 619  glyph "afii10040" 1062 
 620  glyph "afii10041" 1063 
 621  glyph "afii10042" 1064 
 622  glyph "afii10043" 1065 
 623  glyph "afii10044" 1066 
 624  glyph "afii10045" 1067 
 625  glyph "afii10046" 1068 
 626  glyph "afii10047" 1069 
 627  glyph "afii10048" 1070 
 628  glyph "afii10049" 1071 
 629  glyph "afii10050" 1168 
 630  glyph "afii10051" 1026 
 631  glyph "afii10052" 1027 
 632  glyph "afii10053" 1028 
 633  glyph "afii10054" 1029 
 634  glyph "afii10055" 1030 
 635  glyph "afii10056" 1031 
 636  glyph "afii10057" 1032 
 637  glyph "afii10058" 1033 
 638  glyph "afii10059" 1034 
 639  glyph "afii10060" 1035 
 640  glyph "afii10061" 1036 
 641  glyph "afii10062" 1038 
 642  glyph "afii10063" 63172 
 643  glyph "afii10064" 63173 
 644  glyph "afii10065" 1072 
 645  glyph "afii10066" 1073 
 646  glyph "afii10067" 1074 
 647  glyph "afii10068" 1075 
 648  glyph "afii10069" 1076 
 649  glyph "afii10070" 1077 
 650  glyph "afii10071" 1105 
 651  glyph "afii10072" 1078 
 652  glyph "afii10073" 1079 
 653  glyph "afii10074" 1080 
 654  glyph "afii10075" 1081 
 655  glyph "afii10076" 1082 
 656  glyph "afii10077" 1083 
 657  glyph "afii10078" 1084 
 658  glyph "afii10079" 1085 
 659  glyph "afii10080" 1086 
 660  glyph "afii10081" 1087 
 661  glyph "afii10082" 1088 
 662  glyph "afii10083" 1089 
 663  glyph "afii10084" 1090 
 664  glyph "afii10085" 1091 
 665  glyph "afii10086" 1092 
 666  glyph "afii10087" 1093 
 667  glyph "afii10088" 1094 
 668  glyph "afii10089" 1095 
 669  glyph "afii10090" 1096 
 670  glyph "afii10091" 1097 
 671  glyph "afii10092" 1098 
 672  glyph "afii10093" 1099 
 673  glyph "afii10094" 1100 
 674  glyph "afii10095" 1101 
 675  glyph "afii10096" 1102 
 676  glyph "afii10097" 1103 
 677  glyph "afii10098" 1169 
 678  glyph "afii10099" 1106 
 679  glyph "afii10100" 1107 
 680  glyph "afii10101" 1108 
 681  glyph "afii10102" 1109 
 682  glyph "afii10103" 1110 
 683  glyph "afii10104" 1111 
 684  glyph "afii10105" 1112 
 685  glyph "afii10106" 1113 
 686  glyph "afii10107" 1114 
 687  glyph "afii10108" 1115 
 688  glyph "afii10109" 1116 
 689  glyph "afii10110" 1118 
 690  glyph "afii10145" 1039 
 691  glyph "afii10146" 1122 
 692  glyph "afii10147" 1138 
 693  glyph "afii10148" 1140 
 694  glyph "afii10192" 63174 
 695  glyph "afii10193" 1119 
 696  glyph "afii10194" 1123 
 697  glyph "afii10195" 1139 
 698  glyph "afii10196" 1141 
 699  glyph "afii10831" 63175 
 700  glyph "afii10832" 63176 
 701  glyph "afii10846" 1241 
 702  glyph "afii299" 8206 
 703  glyph "afii300" 8207 
 704  glyph "afii301" 8205 
 705  glyph "afii57381" 1642 
 706  glyph "afii57388" 1548 
 707  glyph "afii57392" 1632 
 708  glyph "afii57393" 1633 
 709  glyph "afii57394" 1634 
 710  glyph "afii57395" 1635 
 711  glyph "afii57396" 1636 
 712  glyph "afii57397" 1637 
 713  glyph "afii57398" 1638 
 714  glyph "afii57399" 1639 
 715  glyph "afii57400" 1640 
 716  glyph "afii57401" 1641 
 717  glyph "afii57403" 1563 
 718  glyph "afii57407" 1567 
 719  glyph "afii57409" 1569 
 720  glyph "afii57410" 1570 
 721  glyph "afii57411" 1571 
 722  glyph "afii57412" 1572 
 723  glyph "afii57413" 1573 
 724  glyph "afii57414" 1574 
 725  glyph "afii57415" 1575 
 726  glyph "afii57416" 1576 
 727  glyph "afii57417" 1577 
 728  glyph "afii57418" 1578 
 729  glyph "afii57419" 1579 
 730  glyph "afii57420" 1580 
 731  glyph "afii57421" 1581 
 732  glyph "afii57422" 1582 
 733  glyph "afii57423" 1583 
 734  glyph "afii57424" 1584 
 735  glyph "afii57425" 1585 
 736  glyph "afii57426" 1586 
 737  glyph "afii57427" 1587 
 738  glyph "afii57428" 1588 
 739  glyph "afii57429" 1589 
 740  glyph "afii57430" 1590 
 741  glyph "afii57431" 1591 
 742  glyph "afii57432" 1592 
 743  glyph "afii57433" 1593 
 744  glyph "afii57434" 1594 
 745  glyph "afii57440" 1600 
 746  glyph "afii57441" 1601 
 747  glyph "afii57442" 1602 
 748  glyph "afii57443" 1603 
 749  glyph "afii57444" 1604 
 750  glyph "afii57445" 1605 
 751  glyph "afii57446" 1606 
 752  glyph "afii57448" 1608 
 753  glyph "afii57449" 1609 
 754  glyph "afii57450" 1610 
 755  glyph "afii57451" 1611 
 756  glyph "afii57452" 1612 
 757  glyph "afii57453" 1613 
 758  glyph "afii57454" 1614 
 759  glyph "afii57455" 1615 
 760  glyph "afii57456" 1616 
 761  glyph "afii57457" 1617 
 762  glyph "afii57458" 1618 
 763  glyph "afii57470" 1607 
 764  glyph "afii57505" 1700 
 765  glyph "afii57506" 1662 
 766  glyph "afii57507" 1670 
 767  glyph "afii57508" 1688 
 768  glyph "afii57509" 1711 
 769  glyph "afii57511" 1657 
 770  glyph "afii57512" 1672 
 771  glyph "afii57513" 1681 
 772  glyph "afii57514" 1722 
 773  glyph "afii57519" 1746 
 774  glyph "afii57534" 1749 
 775  glyph "afii57636" 8362 
 776  glyph "afii57645" 1470 
 777  glyph "afii57658" 1475 
 778  glyph "afii57664" 1488 
 779  glyph "afii57665" 1489 
 780  glyph "afii57666" 1490 
 781  glyph "afii57667" 1491 
 782  glyph "afii57668" 1492 
 783  glyph "afii57669" 1493 
 784  glyph "afii57670" 1494 
 785  glyph "afii57671" 1495 
 786  glyph "afii57672" 1496 
 787  glyph "afii57673" 1497 
 788  glyph "afii57674" 1498 
 789  glyph "afii57675" 1499 
 790  glyph "afii57676" 1500 
 791  glyph "afii57677" 1501 
 792  glyph "afii57678" 1502 
 793  glyph "afii57679" 1503 
 794  glyph "afii57680" 1504 
 795  glyph "afii57681" 1505 
 796  glyph "afii57682" 1506 
 797  glyph "afii57683" 1507 
 798  glyph "afii57684" 1508 
 799  glyph "afii57685" 1509 
 800  glyph "afii57686" 1510 
 801  glyph "afii57687" 1511 
 802  glyph "afii57688" 1512 
 803  glyph "afii57689" 1513 
 804  glyph "afii57690" 1514 
 805  glyph "afii57694" 64298 
 806  glyph "afii57695" 64299 
 807  glyph "afii57700" 64331 
 808  glyph "afii57705" 64287 
 809  glyph "afii57716" 1520 
 810  glyph "afii57717" 1521 
 811  glyph "afii57718" 1522 
 812  glyph "afii57723" 64309 
 813  glyph "afii57793" 1460 
 814  glyph "afii57794" 1461 
 815  glyph "afii57795" 1462 
 816  glyph "afii57796" 1467 
 817  glyph "afii57797" 1464 
 818  glyph "afii57798" 1463 
 819  glyph "afii57799" 1456 
 820  glyph "afii57800" 1458 
 821  glyph "afii57801" 1457 
 822  glyph "afii57802" 1459 
 823  glyph "afii57803" 1474 
 824  glyph "afii57804" 1473 
 825  glyph "afii57806" 1465 
 826  glyph "afii57807" 1468 
 827  glyph "afii57839" 1469 
 828  glyph "afii57841" 1471 
 829  glyph "afii57842" 1472 
 830  glyph "afii57929" 700 
 831  glyph "afii61248" 8453 
 832  glyph "afii61289" 8467 
 833  glyph "afii61352" 8470 
 834  glyph "afii61573" 8236 
 835  glyph "afii61574" 8237 
 836  glyph "afii61575" 8238 
 837  glyph "afii61664" 8204 
 838  glyph "afii63167" 1645 
 839  glyph "afii64937" 701 
 840  glyph "agrave" 224 
 841  glyph "aleph" 8501 
 842  glyph "alpha" 945 
 843  glyph "alphatonos" 940 
 844  glyph "amacron" 257 
 845  glyph "ampersand" 38 
 846  glyph "ampersandsmall" 63270 
 847  glyph "angle" 8736 
 848  glyph "angleleft" 9001 
 849  glyph "angleright" 9002 
 850  glyph "anoteleia" 903 
 851  glyph "aogonek" 261 
 852  glyph "approxequal" 8776 
 853  glyph "aring" 229 
 854  glyph "aringacute" 507 
 855  glyph "arrowboth" 8596 
 856  glyph "arrowdblboth" 8660 
 857  glyph "arrowdbldown" 8659 
 858  glyph "arrowdblleft" 8656 
 859  glyph "arrowdblright" 8658 
 860  glyph "arrowdblup" 8657 
 861  glyph "arrowdown" 8595 
 862  glyph "arrowhorizex" 63719 
 863  glyph "arrowleft" 8592 
 864  glyph "arrowright" 8594 
 865  glyph "arrowup" 8593 
 866  glyph "arrowupdn" 8597 
 867  glyph "arrowupdnbse" 8616 
 868  glyph "arrowvertex" 63718 
 869  glyph "asciicircum" 94 
 870  glyph "asciitilde" 126 
 871  glyph "asterisk" 42 
 872  glyph "asteriskmath" 8727 
 873  glyph "asuperior" 63209 
 874  glyph "at" 64 
 875  glyph "atilde" 227 
 876  glyph "b" 98 
 877  glyph "backslash" 92 
 878  glyph "bar" 124 
 879  glyph "beta" 946 
 880  glyph "block" 9608 
 881  glyph "braceex" 63732 
 882  glyph "braceleft" 123 
 883  glyph "braceleftbt" 63731 
 884  glyph "braceleftmid" 63730 
 885  glyph "bracelefttp" 63729 
 886  glyph "braceright" 125 
 887  glyph "bracerightbt" 63742 
 888  glyph "bracerightmid" 63741 
 889  glyph "bracerighttp" 63740 
 890  glyph "bracketleft" 91 
 891  glyph "bracketleftbt" 63728 
 892  glyph "bracketleftex" 63727 
 893  glyph "bracketlefttp" 63726 
 894  glyph "bracketright" 93 
 895  glyph "bracketrightbt" 63739 
 896  glyph "bracketrightex" 63738 
 897  glyph "bracketrighttp" 63737 
 898  glyph "breve" 728 
 899  glyph "brokenbar" 166 
 900  glyph "bsuperior" 63210 
 901  glyph "bullet" 8226 
 902  glyph "c" 99 
 903  glyph "cacute" 263 
 904  glyph "caron" 711 
 905  glyph "carriagereturn" 8629 
 906  glyph "ccaron" 269 
 907  glyph "ccedilla" 231 
 908  glyph "ccircumflex" 265 
 909  glyph "cdotaccent" 267 
 910  glyph "cedilla" 184 
 911  glyph "cent" 162 
 912  glyph "centinferior" 63199 
 913  glyph "centoldstyle" 63394 
 914  glyph "centsuperior" 63200 
 915  glyph "chi" 967 
 916  glyph "circle" 9675 
 917  glyph "circlemultiply" 8855 
 918  glyph "circleplus" 8853 
 919  glyph "circumflex" 710 
 920  glyph "club" 9827 
 921  glyph "colon" 58 
 922  glyph "colonmonetary" 8353 
 923  glyph "comma" 44 
 924  glyph "commaaccent" 63171 
 925  glyph "commainferior" 63201 
 926  glyph "commasuperior" 63202 
 927  glyph "congruent" 8773 
 928  glyph "copyright" 169 
 929  glyph "copyrightsans" 63721 
 930  glyph "copyrightserif" 63193 
 931  glyph "currency" 164 
 932  glyph "cyrBreve" 63185 
 933  glyph "cyrFlex" 63186 
 934  glyph "cyrbreve" 63188 
 935  glyph "cyrflex" 63189 
 936  glyph "d" 100 
 937  glyph "dagger" 8224 
 938  glyph "daggerdbl" 8225 
 939  glyph "dblGrave" 63187 
 940  glyph "dblgrave" 63190 
 941  glyph "dcaron" 271 
 942  glyph "dcroat" 273 
 943  glyph "degree" 176 
 944  glyph "delta" 948 
 945  glyph "diamond" 9830 
 946  glyph "dieresis" 168 
 947  glyph "dieresisacute" 63191 
 948  glyph "dieresisgrave" 63192 
 949  glyph "dieresistonos" 901 
 950  glyph "divide" 247 
 951  glyph "dkshade" 9619 
 952  glyph "dnblock" 9604 
 953  glyph "dollar" 36 
 954  glyph "dollarinferior" 63203 
 955  glyph "dollaroldstyle" 63268 
 956  glyph "dollarsuperior" 63204 
 957  glyph "dong" 8363 
 958  glyph "dotaccent" 729 
 959  glyph "dotbelowcomb" 803 
 960  glyph "dotlessi" 305 
 961  glyph "dotlessj" 63166 
 962  glyph "dotmath" 8901 
 963  glyph "dsuperior" 63211 
 964  glyph "e" 101 
 965  glyph "eacute" 233 
 966  glyph "ebreve" 277 
 967  glyph "ecaron" 283 
 968  glyph "ecircumflex" 234 
 969  glyph "edieresis" 235 
 970  glyph "edotaccent" 279 
 971  glyph "egrave" 232 
 972  glyph "eight" 56 
 973  glyph "eightinferior" 8328 
 974  glyph "eightoldstyle" 63288 
 975  glyph "eightsuperior" 8312 
 976  glyph "element" 8712 
 977  glyph "ellipsis" 8230 
 978  glyph "emacron" 275 
 979  glyph "emdash" 8212 
 980  glyph "emptyset" 8709 
 981  glyph "endash" 8211 
 982  glyph "eng" 331 
 983  glyph "eogonek" 281 
 984  glyph "epsilon" 949 
 985  glyph "epsilontonos" 941 
 986  glyph "equal" 61 
 987  glyph "equivalence" 8801 
 988  glyph "estimated" 8494 
 989  glyph "esuperior" 63212 
 990  glyph "eta" 951 
 991  glyph "etatonos" 942 
 992  glyph "eth" 240 
 993  glyph "exclam" 33 
 994  glyph "exclamdbl" 8252 
 995  glyph "exclamdown" 161 
 996  glyph "exclamdownsmall" 63393 
 997  glyph "exclamsmall" 63265 
 998  glyph "existential" 8707 
 999  glyph "f" 102 
 1000  glyph "female" 9792 
 1001  glyph "ff" 64256 
 1002  glyph "ffi" 64259 
 1003  glyph "ffl" 64260 
 1004  glyph "fi" 64257 
 1005  glyph "figuredash" 8210 
 1006  glyph "filledbox" 9632 
 1007  glyph "filledrect" 9644 
 1008  glyph "five" 53 
 1009  glyph "fiveeighths" 8541 
 1010  glyph "fiveinferior" 8325 
 1011  glyph "fiveoldstyle" 63285 
 1012  glyph "fivesuperior" 8309 
 1013  glyph "fl" 64258 
 1014  glyph "florin" 402 
 1015  glyph "four" 52 
 1016  glyph "fourinferior" 8324 
 1017  glyph "fouroldstyle" 63284 
 1018  glyph "foursuperior" 8308 
 1019  glyph "fraction" 8260 
 1020  glyph "fraction" 8725 
 1021  glyph "franc" 8355 
 1022  glyph "g" 103 
 1023  glyph "gamma" 947 
 1024  glyph "gbreve" 287 
 1025  glyph "gcaron" 487 
 1026  glyph "gcircumflex" 285 
 1027  glyph "gcommaaccent" 291 
 1028  glyph "gdotaccent" 289 
 1029  glyph "germandbls" 223 
 1030  glyph "gradient" 8711 
 1031  glyph "grave" 96 
 1032  glyph "gravecomb" 768 
 1033  glyph "greater" 62 
 1034  glyph "greaterequal" 8805 
 1035  glyph "guillemotleft" 171 
 1036  glyph "guillemotright" 187 
 1037  glyph "guilsinglleft" 8249 
 1038  glyph "guilsinglright" 8250 
 1039  glyph "h" 104 
 1040  glyph "hbar" 295 
 1041  glyph "hcircumflex" 293 
 1042  glyph "heart" 9829 
 1043  glyph "hookabovecomb" 777 
 1044  glyph "house" 8962 
 1045  glyph "hungarumlaut" 733 
 1046  glyph "hyphen" 45 
 1047  glyph "hyphen" 173 
 1048  glyph "hypheninferior" 63205 
 1049  glyph "hyphensuperior" 63206 
 1050  glyph "i" 105 
 1051  glyph "iacute" 237 
 1052  glyph "ibreve" 301 
 1053  glyph "icircumflex" 238 
 1054  glyph "idieresis" 239 
 1055  glyph "igrave" 236 
 1056  glyph "ij" 307 
 1057  glyph "imacron" 299 
 1058  glyph "infinity" 8734 
 1059  glyph "integral" 8747 
 1060  glyph "integralbt" 8993 
 1061  glyph "integralex" 63733 
 1062  glyph "integraltp" 8992 
 1063  glyph "intersection" 8745 
 1064  glyph "invbullet" 9688 
 1065  glyph "invcircle" 9689 
 1066  glyph "invsmileface" 9787 
 1067  glyph "iogonek" 303 
 1068  glyph "iota" 953 
 1069  glyph "iotadieresis" 970 
 1070  glyph "iotadieresistonos" 912 
 1071  glyph "iotatonos" 943 
 1072  glyph "isuperior" 63213 
 1073  glyph "itilde" 297 
 1074  glyph "j" 106 
 1075  glyph "jcircumflex" 309 
 1076  glyph "k" 107 
 1077  glyph "kappa" 954 
 1078  glyph "kcommaaccent" 311 
 1079  glyph "kgreenlandic" 312 
 1080  glyph "l" 108 
 1081  glyph "lacute" 314 
 1082  glyph "lambda" 955 
 1083  glyph "lcaron" 318 
 1084  glyph "lcommaaccent" 316 
 1085  glyph "ldot" 320 
 1086  glyph "less" 60 
 1087  glyph "lessequal" 8804 
 1088  glyph "lfblock" 9612 
 1089  glyph "lira" 8356 
 1090  glyph "ll" 63168 
 1091  glyph "logicaland" 8743 
 1092  glyph "logicalnot" 172 
 1093  glyph "logicalor" 8744 
 1094  glyph "longs" 383 
 1095  glyph "lozenge" 9674 
 1096  glyph "lslash" 322 
 1097  glyph "lsuperior" 63214 
 1098  glyph "ltshade" 9617 
 1099  glyph "m" 109 
 1100  glyph "macron" 175 
 1101  glyph "macron" 713 
 1102  glyph "male" 9794 
 1103  glyph "minus" 8722 
 1104  glyph "minute" 8242 
 1105  glyph "msuperior" 63215 
 1106  glyph "mu" 181 
 1107  glyph "mu" 956 
 1108  glyph "multiply" 215 
 1109  glyph "musicalnote" 9834 
 1110  glyph "musicalnotedbl" 9835 
 1111  glyph "n" 110 
 1112  glyph "nacute" 324 
 1113  glyph "napostrophe" 329 
 1114  glyph "ncaron" 328 
 1115  glyph "ncommaaccent" 326 
 1116  glyph "nine" 57 
 1117  glyph "nineinferior" 8329 
 1118  glyph "nineoldstyle" 63289 
 1119  glyph "ninesuperior" 8313 
 1120  glyph "notelement" 8713 
 1121  glyph "notequal" 8800 
 1122  glyph "notsubset" 8836 
 1123  glyph "nsuperior" 8319 
 1124  glyph "ntilde" 241 
 1125  glyph "nu" 957 
 1126  glyph "numbersign" 35 
 1127  glyph "o" 111 
 1128  glyph "oacute" 243 
 1129  glyph "obreve" 335 
 1130  glyph "ocircumflex" 244 
 1131  glyph "odieresis" 246 
 1132  glyph "oe" 339 
 1133  glyph "ogonek" 731 
 1134  glyph "ograve" 242 
 1135  glyph "ohorn" 417 
 1136  glyph "ohungarumlaut" 337 
 1137  glyph "omacron" 333 
 1138  glyph "omega" 969 
 1139  glyph "omega1" 982 
 1140  glyph "omegatonos" 974 
 1141  glyph "omicron" 959 
 1142  glyph "omicrontonos" 972 
 1143  glyph "one" 49 
 1144  glyph "onedotenleader" 8228 
 1145  glyph "oneeighth" 8539 
 1146  glyph "onefitted" 63196 
 1147  glyph "onehalf" 189 
 1148  glyph "oneinferior" 8321 
 1149  glyph "oneoldstyle" 63281 
 1150  glyph "onequarter" 188 
 1151  glyph "onesuperior" 185 
 1152  glyph "onethird" 8531 
 1153  glyph "openbullet" 9702 
 1154  glyph "ordfeminine" 170 
 1155  glyph "ordmasculine" 186 
 1156  glyph "orthogonal" 8735 
 1157  glyph "oslash" 248 
 1158  glyph "oslashacute" 511 
 1159  glyph "osuperior" 63216 
 1160  glyph "otilde" 245 
 1161  glyph "p" 112 
 1162  glyph "paragraph" 182 
 1163  glyph "parenleft" 40 
 1164  glyph "parenleftbt" 63725 
 1165  glyph "parenleftex" 63724 
 1166  glyph "parenleftinferior" 8333 
 1167  glyph "parenleftsuperior" 8317 
 1168  glyph "parenlefttp" 63723 
 1169  glyph "parenright" 41 
 1170  glyph "parenrightbt" 63736 
 1171  glyph "parenrightex" 63735 
 1172  glyph "parenrightinferior" 8334 
 1173  glyph "parenrightsuperior" 8318 
 1174  glyph "parenrighttp" 63734 
 1175  glyph "partialdiff" 8706 
 1176  glyph "percent" 37 
 1177  glyph "period" 46 
 1178  glyph "periodcentered" 183 
 1179  glyph "periodcentered" 8729 
 1180  glyph "periodinferior" 63207 
 1181  glyph "periodsuperior" 63208 
 1182  glyph "perpendicular" 8869 
 1183  glyph "perthousand" 8240 
 1184  glyph "peseta" 8359 
 1185  glyph "phi" 966 
 1186  glyph "phi1" 981 
 1187  glyph "pi" 960 
 1188  glyph "plus" 43 
 1189  glyph "plusminus" 177 
 1190  glyph "prescription" 8478 
 1191  glyph "product" 8719 
 1192  glyph "propersubset" 8834 
 1193  glyph "propersuperset" 8835 
 1194  glyph "proportional" 8733 
 1195  glyph "psi" 968 
 1196  glyph "q" 113 
 1197  glyph "question" 63 
 1198  glyph "questiondown" 191 
 1199  glyph "questiondownsmall" 63423 
 1200  glyph "questionsmall" 63295 
 1201  glyph "quotedbl" 34 
 1202  glyph "quotedblbase" 8222 
 1203  glyph "quotedblleft" 8220 
 1204  glyph "quotedblright" 8221 
 1205  glyph "quoteleft" 8216 
 1206  glyph "quotereversed" 8219 
 1207  glyph "quoteright" 8217 
 1208  glyph "quotesinglbase" 8218 
 1209  glyph "quotesingle" 39 
 1210  glyph "r" 114 
 1211  glyph "racute" 341 
 1212  glyph "radical" 8730 
 1213  glyph "radicalex" 63717 
 1214  glyph "rcaron" 345 
 1215  glyph "rcommaaccent" 343 
 1216  glyph "reflexsubset" 8838 
 1217  glyph "reflexsuperset" 8839 
 1218  glyph "registered" 174 
 1219  glyph "registersans" 63720 
 1220  glyph "registerserif" 63194 
 1221  glyph "revlogicalnot" 8976 
 1222  glyph "rho" 961 
 1223  glyph "ring" 730 
 1224  glyph "rsuperior" 63217 
 1225  glyph "rtblock" 9616 
 1226  glyph "rupiah" 63197 
 1227  glyph "s" 115 
 1228  glyph "sacute" 347 
 1229  glyph "scaron" 353 
 1230  glyph "scedilla" 351 
 1231  glyph "scedilla" 63170 
 1232  glyph "scircumflex" 349 
 1233  glyph "scommaaccent" 537 
 1234  glyph "second" 8243 
 1235  glyph "section" 167 
 1236  glyph "semicolon" 59 
 1237  glyph "seven" 55 
 1238  glyph "seveneighths" 8542 
 1239  glyph "seveninferior" 8327 
 1240  glyph "sevenoldstyle" 63287 
 1241  glyph "sevensuperior" 8311 
 1242  glyph "shade" 9618 
 1243  glyph "sigma" 963 
 1244  glyph "sigma1" 962 
 1245  glyph "similar" 8764 
 1246  glyph "six" 54 
 1247  glyph "sixinferior" 8326 
 1248  glyph "sixoldstyle" 63286 
 1249  glyph "sixsuperior" 8310 
 1250  glyph "slash" 47 
 1251  glyph "smileface" 9786 
 1252  glyph "space" 32 
 1253  glyph "space" 160 
 1254  glyph "spade" 9824 
 1255  glyph "ssuperior" 63218 
 1256  glyph "sterling" 163 
 1257  glyph "suchthat" 8715 
 1258  glyph "summation" 8721 
 1259  glyph "sun" 9788 
 1260  glyph "t" 116 
 1261  glyph "tau" 964 
 1262  glyph "tbar" 359 
 1263  glyph "tcaron" 357 
 1264  glyph "tcommaaccent" 355 
 1265  glyph "tcommaaccent" 539 
 1266  glyph "therefore" 8756 
 1267  glyph "theta" 952 
 1268  glyph "theta1" 977 
 1269  glyph "thorn" 254 
 1270  glyph "three" 51 
 1271  glyph "threeeighths" 8540 
 1272  glyph "threeinferior" 8323 
 1273  glyph "threeoldstyle" 63283 
 1274  glyph "threequarters" 190 
 1275  glyph "threequartersemdash" 63198 
 1276  glyph "threesuperior" 179 
 1277  glyph "tilde" 732 
 1278  glyph "tildecomb" 771 
 1279  glyph "tonos" 900 
 1280  glyph "trademark" 8482 
 1281  glyph "trademarksans" 63722 
 1282  glyph "trademarkserif" 63195 
 1283  glyph "triagdn" 9660 
 1284  glyph "triaglf" 9668 
 1285  glyph "triagrt" 9658 
 1286  glyph "triagup" 9650 
 1287  glyph "tsuperior" 63219 
 1288  glyph "two" 50 
 1289  glyph "twodotenleader" 8229 
 1290  glyph "twoinferior" 8322 
 1291  glyph "twooldstyle" 63282 
 1292  glyph "twosuperior" 178 
 1293  glyph "twothirds" 8532 
 1294  glyph "u" 117 
 1295  glyph "uacute" 250 
 1296  glyph "ubreve" 365 
 1297  glyph "ucircumflex" 251 
 1298  glyph "udieresis" 252 
 1299  glyph "ugrave" 249 
 1300  glyph "uhorn" 432 
 1301  glyph "uhungarumlaut" 369 
 1302  glyph "umacron" 363 
 1303  glyph "underscore" 95 
 1304  glyph "underscoredbl" 8215 
 1305  glyph "union" 8746 
 1306  glyph "universal" 8704 
 1307  glyph "uogonek" 371 
 1308  glyph "upblock" 9600 
 1309  glyph "upsilon" 965 
 1310  glyph "upsilondieresis" 971 
 1311  glyph "upsilondieresistonos" 944 
 1312  glyph "upsilontonos" 973 
 1313  glyph "uring" 367 
 1314  glyph "utilde" 361 
 1315  glyph "v" 118 
 1316  glyph "w" 119 
 1317  glyph "wacute" 7811 
 1318  glyph "wcircumflex" 373 
 1319  glyph "wdieresis" 7813 
 1320  glyph "weierstrass" 8472 
 1321  glyph "wgrave" 7809 
 1322  glyph "x" 120 
 1323  glyph "xi" 958 
 1324  glyph "y" 121 
 1325  glyph "yacute" 253 
 1326  glyph "ycircumflex" 375 
 1327  glyph "ydieresis" 255 
 1328  glyph "yen" 165 
 1329  glyph "ygrave" 7923 
 1330  glyph "z" 122 
 1331  glyph "zacute" 378 
 1332  glyph "zcaron" 382 
 1333  glyph "zdotaccent" 380 
 1334  glyph "zero" 48 
 1335  glyph "zeroinferior" 8320 
 1336  glyph "zerooldstyle" 63280 
 1337  glyph "zerosuperior" 8304 
 1338  glyph "zeta" 950 
 1339   
 1340   
 1341  if false 
 1342   
 1343    function unhexa s -> i 
 1344      arg Str s ; arg Int i 
 1345      i := 0 
 1346      for (var Int j) 0 s:len-1 
 1347        var Int c := s:j number 
 1348        if c>="0":0:number and c<="9":0:number 
 1349          i := i*16+(c-"0":0:number) 
 1350        eif c>="A":0:number and c<="F":0:number 
 1351          i := i*16+(c-"A":0:number+10) 
 1352        eif c>="a":0:number and c<="f":0:number 
 1353          i := i*16+(c-"a":0:number+10) 
 1354        else 
 1355          return undefined 
 1356     
 1357    function parse_glyphs_list 
 1358      (var Stream s) open "file:/backup/doc/unicode/glyphlist.txt" in 
 1359      while not s:atend 
 1360        if (s:readline parse any:(var Str h) ";" any:(var Str glyph) ";" any) 
 1361          console "glyph " string:glyph " " unhexa:h eol 
 1362   
 1363    parse_glyphs_list 
 1364   
 1365  if auto_accent 
 1366   
 1367    type FontAccent 
 1368      field Int base accent 
 1369     
 1370    gvar (Dictionary Int FontAccent) accents 
 1371    function fill_accents 
 1372      each postscript_glyphs 
 1373        var Str := postscript_glyphs key g 
 1374        if n:len>=4 
 1375          var Pointer:Int base :> postscript_glyphs first (0 1) 
 1376          var Pointer:Int accent :> postscript_glyphs first (n:len) 
 1377          if exists:base and exists:accent 
 1378            var FontAccent a ; base := base ; accent := accent 
 1379            accents insert a 
 1380            # console n " = " base " + " accent eol 
 1381    fill_accents 
 1382   
 1383   
 1384  public 
 1385   
 1386    type FontChar 
 1387      field Str char_name 
 1388      field Array:Curve curves 
 1389      field Vector2 vector <- (vector 1 0) 
 1390      field Float bbox_x0 bbox_y0 bbox_x1 bbox_y1 <- 0 
 1391   
 1392  if raster_fonts 
 1393   
 1394    type FontRaster 
 1395      inherit CachePrototype 
 1396      field (Dictionary Int Address) chars 
 1397      field Sem sem 
 1398     
 1399    CachePrototype maybe FontRaster 
 1400   
 1401    function destroy fr 
 1402      arg_w FontRaster fr 
 1403      each fr:chars 
 1404        memory_free a 
 1405   
 1406  public 
 1407   
 1408    type Font 
 1409      inherit CachePrototype 
 1410      field (Dictionary Int FontChar) chars 
 1411      field Vector2 vector <- (vector 1 0) 
 1412      field Float bbox_x0 bbox_y0 bbox_x1 bbox_y1 <- 0 
 1413      field Str file 
 1414      # Pliant way to identify 
 1415      field Str family 
 1416      field Str fullname 
 1417      field Str psname 
 1418      field Str id 
 1419      # extra informations 
 1420      field Array:Int encoding 
 1421      field Str options 
 1422      field CBool fixed <- false 
 1423      if type1details 
 1424        field Str weight 
 1425        field Float italic <- 0 
 1426   
 1427  CachePrototype maybe Font 
 1428   
 1429   
 1430  type FontContext 
 1431    field Str filename 
 1432    field (Dictionary Str Str) defs 
 1433    field Array:Str subrs 
 1434    field Array:Float stack stack2 
 1435    field Point2 cp 
 1436    field Pointer:Curve cc 
 1437    field Pointer:FontChar ch 
 1438   
 1439  method fc push f 
 1440    arg_rw FontContext fc ; arg Float f 
 1441    fc stack += f 
 1442   
 1443  method fc pop n 
 1444    arg_rw FontContext fc ; arg Int n 
 1445    fc:stack size -= n 
 1446   
 1447  method fc count -> n 
 1448    arg FontContext fc ; arg Int n 
 1449    := fc:stack size 
 1450   
 1451  method fc st i -> f 
 1452    arg FontContext fc ; arg Int i ; arg_C Float f 
 1453    :> fc:stack fc:stack:size-1-i 
 1454   
 1455  method fc newcurve -> c 
 1456    arg_rw FontContext fc ; arg_C Curve c 
 1457    fc:ch:curves size += 1 
 1458    :> fc:ch:curves fc:ch:curves:size-1 
 1459   
 1460  method fc lastpoint i -> p 
 1461    arg FontContext fc ; arg Int i ; arg_C CurvePoint p 
 1462    :> fc:cc point fc:cc:size-1-i 
 1463   
 1464   
 1465  method fc open_char_def c name 
 1466    arg_rw FontContext fc ; arg_rw FontChar c ; arg Str name 
 1467    char_name := name 
 1468    vector := vector 0 0 
 1469    fc ch :> c 
 1470   
 1471   
 1472  function init_bbox x0 y0 x1 y1 
 1473    arg_w Float x0 y0 x1 y1 
 1474    x0 := float_max 
 1475    y0 := float_max 
 1476    x1 := float_min 
 1477    y1 := float_min 
 1478     
 1479  function update_bbox x0 y0 x1 y1 xx0 yy0 xx1 yy1 
 1480    arg_rw Float x0 y0 x1 y1 ; arg Float xx0 yy0 xx1 yy1 
 1481    x0 := min x0 xx0 
 1482    y0 := min y0 yy0 
 1483    x1 := max x1 xx1 
 1484    y1 := max y1 yy1 
 1485   
 1486  function terminate_bbox x0 y0 x1 y1 
 1487    arg_rw Float x0 y0 x1 y1 
 1488    if x0=float_max 
 1489      x0 := 0 
 1490      y0 := 0 
 1491      x1 := 0 
 1492      y1 := 0 
 1493     
 1494   
 1495  method fc close_char_def 
 1496    arg_rw FontContext fc 
 1497    var Pointer:FontChar :> fc ch 
 1498    c:vector /= 1000 ; c:vector /= 1000 
 1499    init_bbox c:bbox_x0 c:bbox_y0 c:bbox_x1 c:bbox_y1 
 1500    var Int := 0 
 1501    while i<c:curves:size 
 1502      var Pointer:Curve crv :> c:curves i 
 1503      for (var Int j) crv:size-1 
 1504        var Pointer:CurvePoint :> crv point j 
 1505        /= 1000 ; /= 1000 
 1506        in_x /= 1000 ; in_y /= 1000 
 1507        out_x /= 1000 ; out_y /= 1000 
 1508      crv compute bezier 
 1509      if crv=success 
 1510        crv bbox (var Float x0) (var Float y0) (var Float x1) (var Float y1) 
 1511        update_bbox c:bbox_x0 c:bbox_y0 c:bbox_x1 c:bbox_y1 x0 y0 x1 y1 
 1512        += 1 
 1513      else 
 1514        for (var Int j) c:curves:size-2 
 1515          swap (c:curves j) (c:curves j+1) 
 1516        c:curves size -= 1 
 1517    terminate_bbox c:bbox_x0 c:bbox_y0 c:bbox_x1 c:bbox_y1 
 1518   
 1519   
 1520  method fc interprete prog 
 1521    arg_rw FontContext fc ; arg Str prog 
 1522    implicit fc 
 1523      var Str := prog ; var Str r 
 1524      while p<>"" 
 1525        if (parse (var Float f) any:r) 
 1526          push f 
 1527        eif (parse word:"rlineto" any:r) and count>=2 
 1528          cp += st 1 ; cp -= st 0 
 1529          cc angle cp:cp:y 
 1530          pop 2 
 1531        eif (parse word:"hlineto" any:r) and count>=1 
 1532          cp += st 0 
 1533          cc angle cp:cp:y 
 1534          pop 1 
 1535        eif (parse word:"vlineto" any:r) and count>=1 
 1536          cp -= st 0 
 1537          cc angle cp:cp:y 
 1538          pop 1 
 1539        eif (parse word:"rmoveto" any:r) and count>=2 
 1540          cp += st 1 ; cp -= st 0 
 1541          cc :> newcurve 
 1542          cc angle cp:cp:y 
 1543          pop 2 
 1544        eif (parse word:"hmoveto" any:r) and count>=1 
 1545          cp += st 0 
 1546          cc :> newcurve 
 1547          cc angle cp:cp:y 
 1548          pop 1 
 1549        eif (parse word:"vmoveto" any:r) and count>=1 
 1550          cp -= st 0 
 1551          cc :> newcurve 
 1552          cc angle cp:cp:y 
 1553          pop 1 
 1554        eif (parse word:"rrcurveto" any:r) and count>=6 
 1555          var Point2 p1 := cp+(vector st:-(st:4)) 
 1556          var Point2 p2 := p1+(vector st:-(st:2)) 
 1557          var Point2 p3 := p2+(vector st:-(st:0)) 
 1558          cp := p3 
 1559          cc angle cp:cp:y 
 1560          var Pointer:CurvePoint cp0 :> lastpoint 0 
 1561          var Pointer:CurvePoint cp1 :> lastpoint 1 
 1562          cp1 out p1:x-cp1:p1:y-cp1:y 
 1563          cp0 in p2:x-cp0:p2:y-cp0:y 
 1564          pop 6 
 1565        eif (parse word:"hvcurveto" any:r) and count>=4 
 1566          var Point2 p1 := cp+(vector st:3 0) 
 1567          var Point2 p2 := p1+(vector st:-(st:1)) 
 1568          var Point2 p3 := p2+(vector -(st:0)) 
 1569          cp := p3 
 1570          cc angle cp:cp:y 
 1571          var Pointer:CurvePoint cp0 :> lastpoint 0 
 1572          var Pointer:CurvePoint cp1 :> lastpoint 1 
 1573          cp1 out p1:x-cp1:p1:y-cp1:y 
 1574          cp0 in p2:x-cp0:p2:y-cp0:y 
 1575          pop 4 
 1576        eif (parse word:"vhcurveto" any:r) and count>=4 
 1577          var Point2 p1 := cp+(vector -(st:3)) 
 1578          var Point2 p2 := p1+(vector st:-(st:1)) 
 1579          var Point2 p3 := p2+(vector st:0 0) 
 1580          cp := p3 
 1581          cc angle cp:cp:y 
 1582          var Pointer:CurvePoint cp0 :> lastpoint 0 
 1583          var Pointer:CurvePoint cp1 :> lastpoint 1 
 1584          cp1 out p1:x-cp1:p1:y-cp1:y 
 1585          cp0 in p2:x-cp0:p2:y-cp0:y 
 1586          pop 4 
 1587        eif (parse word:"hsbw" any:r) and count>=2 
 1588          cp := point st:1 0 
 1589          ch vector := vector st:0 0 
 1590          pop 2 
 1591        eif (parse word:"sbw" any:r) and count>=4 
 1592          cp := point st:-(st:2) 
 1593          ch vector := vector st:-(st:0) 
 1594          pop 4 
 1595        eif (parse word:"seac" any:r) and count>=5 
 1596          var Vector2 := ch vector 
 1597          var Int := cast st:Int 
 1598          var Int := cast st:Int 
 1599          var Vector2 := vector st:3-st:-(st:2) 
 1600          pop 5 
 1601          if exists:(defs first string:a) # shoud be std_ev:a 
 1602            interprete (defs string:a) 
 1603          for (var Int n) ch:curves:size-1 
 1604            var Pointer:Curve :> ch:curves n 
 1605            for (var Int i) c:size 
 1606              var Pointer:CurvePoint pp :> point i 
 1607              pp += x ; pp += y 
 1608          if exists:(defs first string:b) # shoud be std_ev:b 
 1609            interprete (defs string:b) 
 1610          ch vector := v 
 1611        eif (parse word:"hstem" any:r) and count>=2 
 1612          pop 2 
 1613        eif (parse word:"hstem3" any:r) and count>=5 
 1614          pop 6 
 1615        eif (parse word:"vstem" any:r) and count>=2 
 1616          pop 2 
 1617        eif (parse word:"vstem3" any:r) and count>=5 
 1618          pop 6 
 1619        eif (parse word:"div" any:r) and count>=2 
 1620          st /= st 0 
 1621          pop 1 
 1622        eif (parse word:"callsubr" any:r) and count>=1 
 1623          var Int := cast st:Int 
 1624          pop 1 
 1625          if i>=and i<subrs:size 
 1626            interprete subrs:i 
 1627        eif (parse word:"callothersubr" any:r) and count>=and { var Int := cast st:Int ; count>=2+n } 
 1628          pop 2 
 1629          for (var Int u) n-1 
 1630            stack2 += st 0 
 1631            pop 1 
 1632        eif (parse word:"pop" any:r) and stack2:size>=0 
 1633          push (stack2 stack2:size-1) 
 1634          fc:stack2 size -= 1 
 1635        eif (parse word:"return" any:r) 
 1636          void 
 1637        eif (parse word:"dotsection" any:r) 
 1638          void 
 1639        eif (parse word:"closepath" any:r) 
 1640          void 
 1641        eif (parse word:"endchar" any:r) 
 1642          void 
 1643        else 
 1644          console "Failed to parse definition " " in " filename " (stack size is " count ")" eol 
 1645          return 
 1646        := r 
 1647   
 1648  method f load_postscript filename options -> status 
 1649    arg_rw Font f ; arg Str filename options ; arg Status status 
 1650    var Link:Stream :> new Stream 
 1651    if false 
 1652      s open "pfb:"+filename in+safe 
 1653      (var Stream clear) open "file:/tmp/font.txt" out+safe 
 1654      while not s:atend 
 1655        clear writeline s:readline 
 1656      clear close 
 1657    open "pfb:"+filename in+safe 
 1658    if s=failure or not (s:readline parse "%!" any) 
 1659      open filename in+safe 
 1660      if s=failure or not (s:readline parse "%!" any) 
 1661        return failure 
 1662    file := filename 
 1663    var FontContext ctx ; ctx filename := filename 
 1664    # console filename eol 
 1665    while not s:atend 
 1666      var Str := readline 
 1667      # console "  " l eol 
 1668      if (parse word:"/FontName" "/" any:(var Str n) word:"def") 
 1669        psname := n 
 1670      eif (parse word:"/FullName" "(" any:(var Str n) ")" word:"readonly" word:"def") 
 1671        fullname := n 
 1672      eif (parse word:"/FamilyName" "(" any:(var Str n) ")" word:"readonly" word:"def") 
 1673        family := n 
 1674      eif type1details and (l parse word:"/Weight" "(" any:(var Str n) ")" word:"readonly" word:"def") 
 1675        f weight := n 
 1676      eif type1details and (l parse word:"/ItalicAngle" (var Float ff) word:"def") 
 1677        f italic := ff 
 1678      eif (parse word:"/isFixedPitch" any:(var Str n) word:"def") 
 1679        fixed := n="true" 
 1680      eif (parse word:"/FontBBox" "{" (var Int ix0) (var Int iy0) (var Int ix1) (var Int iy1) "}" word:"def") 
 1681        bbox_x0 := ix0/1000 
 1682        bbox_y0 := -iy1/1000 
 1683        bbox_x1 := ix1/1000 
 1684        bbox_y1 := -iy0/1000 
 1685      eif (parse word:"dup" (var Int i) "{" any:(var Str d) "}" "|"or (parse word:"dup" (var Int i) "{" any:(var Str d) "}" word:"noaccess" word:"put"or (parse word:"dup" (var Int i) "{" any:(var Str d) "}" word:"NP") 
 1686        if i>=and i<2^16 
 1687          if i>=ctx:subrs:size 
 1688            ctx:subrs size := i+1 
 1689          ctx:subrs := d 
 1690      eif (parse "/" any:(var Str n) "{" any:(var Str d) "}" "|-"or (parse "/" any:(var Str n) "{" any:(var Str d) "}" word:"ND") 
 1691        ctx:defs insert d 
 1692      eif (parse word:"dup" (var Int i) "/" any:(var Str n) _ word:"put") 
 1693        var Pointer:Int num :> postscript_glyphs first n 
 1694        if i>=and i<256 and exists:num 
 1695          while f:encoding:size<=i 
 1696            f:encoding += undefined 
 1697          f:encoding := num 
 1698      else 
 1699        void 
 1700        # console "font line " l eol 
 1701    each def ctx:defs 
 1702      var Str := ctx:defs key def 
 1703      var Pointer:Int num :> postscript_glyphs first n 
 1704      if exists:num 
 1705        var FontChar new_ch := var FontChar empty_char 
 1706        ctx open_char_def new_ch n 
 1707        ctx interprete def 
 1708        ctx close_char_def 
 1709        if not auto_accent or not exists:(accents first num) or new_ch:curves:size>0 
 1710          f:chars insert num new_ch 
 1711      else 
 1712        void 
 1713        # console "unsupported glyph " def eol 
 1714    if f:bbox_x0=and f:bbox_y0=and f:bbox_x1=and f:bbox_y1=0 
 1715      each ch f:chars 
 1716        for (var Int j) ch:curves:size-1 
 1717          ch:curves:bbox (var Float x0) (var Float y0) (var Float x1) (var Float y1) 
 1718          if x0=defined 
 1719            update_bbox f:bbox_x0 f:bbox_y0 f:bbox_x1 f:bbox_y1 x0 y0 x1 y1 
 1720    if (options option "fixed") 
 1721      fixed := true 
 1722      var Pointer:FontChar ch :> f:chars first " ":number 
 1723      if exists:ch 
 1724        vector := ch vector 
 1725    id := file_md5_hexa_signature filename 
 1726    if verbose 
 1727      console "  loaded font " f:fullname " from file " f:file eol 
 1728    status := success 
 1729   
 1730  function font_postscript filename options -> f 
 1731    arg Str filename options ; arg Link:Font f 
 1732    :> new Font 
 1733    if (load_postscript filename options)=failure 
 1734      :> null map Font 
 1735   
 1736  export postscript_glyphs '. load_postscript' font_postscript 
 1737   
 1738   
 1739 
 
 1740  # Basic queries 
 1741   
 1742   
 1743  method f curves char_num -> curves 
 1744    arg Font f ; arg Int char_num ; arg Array:Curve curves 
 1745    curves size := 0 
 1746    var Pointer:FontChar ch :> f:chars first char_num 
 1747    if exists:ch 
 1748      curves := ch curves 
 1749    eif auto_accent and { var Pointer:FontAccent :> accents first char_num ; exists a } 
 1750      var Pointer:FontChar base :> f:chars first a:base 
 1751      var Pointer:FontChar accent :> f:chars first a:accent 
 1752      if exists:base and exists:accent 
 1753        curves size := base:curves:size+accent:curves:size 
 1754        for (var Int i) base:curves:size 
 1755          curves := base:curves:i 
 1756        for (var Int i) accent:curves:size 
 1757          curves base:curves:size+:= accent:curves:i 
 1758      else 
 1759        curves size := 0 
 1760    else 
 1761      curves size := 0 
 1762   
 1763   
 1764  method f vector char_num -> v 
 1765    arg Font f ; arg Int char_num ; arg Vector2 v 
 1766    var Pointer:FontChar ch :> f:chars first char_num 
 1767    if auto_accent and not exists:ch and { var Pointer:FontAccent :> accents first char_num ; exists a } 
 1768      ch :> f:chars first a:base 
 1769    if exists:ch 
 1770      := ch vector 
 1771    else 
 1772      := vector 
 1773   
 1774  method f bbox char_num x0 y0 x1 y1 
 1775    arg Font f ; arg Int char_num ; arg_w Float x0 y0 x1 y1 
 1776    var Pointer:FontChar ch :> f:chars first char_num 
 1777    if auto_accent and not exists:ch and { var Pointer:FontAccent :> accents first char_num ; exists a } 
 1778      ch :> f:chars first a:base 
 1779    if exists:ch 
 1780      x0 := ch bbox_x0 ; y0 := ch bbox_y0 ; x1 := ch bbox_x1 ; y1 := ch bbox_y1 
 1781    else 
 1782      x0 := bbox_x0 ; y0 := bbox_y0 ; x1 := bbox_x1 ; y1 := bbox_y1 
 1783   
 1784   
 1785  export Font '. family' '. fullname' '. psname' '. id' 
 1786  if type1details 
 1787    export '. weight' '. italic' 
 1788  export '. fixed' 
 1789  export '. curves' '. vector' '. bbox' 
 1790   
 1791   
 1792 
 
 1793  # Advanced queries 
 1794   
 1795   
 1796  function character_number buffer i csize -> num 
 1797    arg Address buffer ; arg Int csize num 
 1798    if csize=1 
 1799      num := buffer map uInt8 i 
 1800    eif csize=4 
 1801      num := buffer map Int32 i 
 1802   
 1803  method f vector buffer count csize kerning -> v 
 1804    arg Font f ; arg Address buffer ; arg Int count csize ; arg Address kerning ; arg Vector2 v 
 1805    if f:fixed and kerning=null 
 1806      return count*f:vector 
 1807    := vector 0 0 
 1808    for (var Int i) count-1 
 1809      if kerning<>null 
 1810        += (kerning map Float i)*f:vector 
 1811      += vector (character_number buffer csize) 
 1812   
 1813  method f vector text kerning -> v 
 1814    arg Font f ; arg Str text ; arg Address kerning ; arg Vector2 v 
 1815    := vector text:characters text:len kerning 
 1816   
 1817  method f vector text kerning -> v 
 1818    arg Font f ; arg Str32 text ; arg Address kerning ; arg Vector2 v 
 1819    := vector text:characters text:len kerning 
 1820   
 1821   
 1822  method f length text kerning -> w 
 1823    arg Font f ; arg Str text ; arg Address kerning ; arg Float w 
 1824    := (vector text:characters text:len kerning) length 
 1825   
 1826  method f length text kerning -> w 
 1827    arg Font f ; arg Str32 text ; arg Address kerning ; arg Float w 
 1828    := (vector text:characters text:len kerning) length 
 1829   
 1830   
 1831  public 
 1832    constant bbox_l 1 # lengthwise optimised 
 1833    constant bbox_h 2 # orthogonal optimised 
 1834   
 1835  method f bbox buffer count csize kerning flags x0 y0 x1 y1 
 1836    arg Font f ; arg Address buffer ; arg Int count csize ; arg Address kerning ; arg Int flags ; arg_w Float x0 y0 x1 y1 
 1837    init_bbox x0 y0 x1 y1 
 1838    if (flags .and. bbox_l)=or count=0 
 1839      var Vector2 := vector buffer count csize kerning 
 1840      update_bbox x0 y0 x1 y1 0 0 v:v:y 
 1841    eif (flags .and. bbox_h)=0 
 1842      bbox (character_number buffer csize) (var Float cx0) (var Float cy0) (var Float cx1) (var Float cy1) 
 1843      update_bbox x0 y0 x1 y1 cx0 cy0 cx1 cy1 
 1844      var Vector2 := vector buffer count-csize kerning 
 1845      if kerning<>null 
 1846        += (kerning map Float count-1)*f:vector 
 1847      bbox (character_number buffer count-csize) (var Float cx0) (var Float cy0) (var Float cx1) (var Float cy1) 
 1848      update_bbox x0 y0 x1 y1 v:x+cx0 v:y+cy0 v:x+cx1 v:y+cy1 
 1849    if (flags .and. bbox_h)=0 
 1850      if f:vector:y<>0 
 1851        x0 := bbox_x0 
 1852        x1 := bbox_x1 
 1853      if f:vector:x<>0 
 1854        y0 := bbox_y0 
 1855        y1 := bbox_y1 
 1856    else 
 1857      var Vector2 := vector 0 0 
 1858      for (var Int i) count-1 
 1859        if kerning<>null 
 1860          += (kerning map Float count-1)*f:vector 
 1861        var Int num := character_number buffer csize 
 1862        bbox num (var Float cx0) (var Float cy0) (var Float cx1) (var Float cy1) 
 1863        update_bbox x0 y0 x1 y1 v:x+cx0 v:y+cy0 v:x+cx1 v:y+cy1 
 1864        += vector num 
 1865    terminate_bbox x0 y0 x1 y1 
 1866   
 1867  method f bbox text kerning flags scale x0 y0 x1 y1 
 1868    arg Font f ; arg Str text ; arg Address kerning ; arg Int flags ; arg Float scale ; arg_w Float x0 y0 x1 y1 
 1869    bbox text:characters text:len kerning flags x0 y0 x1 y1 
 1870    x0 *= scale ; y0 *= scale ; x1 *= scale ; y1 *= scale 
 1871   
 1872  method f bbox text kerning x0 y0 x1 y1 
 1873    arg Font f ; arg Str text ; arg Address kerning ; arg_w Float x0 y0 x1 y1 
 1874    bbox text:characters text:len kerning x0 y0 x1 y1 
 1875   
 1876  method f bbox text kerning flags scale x0 y0 x1 y1 
 1877    arg Font f ; arg Str32 text ; arg Address kerning ; arg Int flags ; arg Float scale ; arg_w Float x0 y0 x1 y1 
 1878    bbox text:characters text:len kerning flags x0 y0 x1 y1 
 1879    x0 *= scale ; y0 *= scale ; x1 *= scale ; y1 *= scale 
 1880   
 1881  method f bbox text kerning x0 y0 x1 y1 
 1882    arg Font f ; arg Str32 text ; arg Address kerning ; arg_w Float x0 y0 x1 y1 
 1883    bbox text:characters text:len kerning x0 y0 x1 y1 
 1884   
 1885  export '. length' '. vector' '. bbox' 
 1886   
 1887   
 1888 
 
 1889  # Drawing text 
 1890   
 1891   
 1892  module "/pliant/graphic/image/prototype.pli" 
 1893  module "/pliant/graphic/image/pixmap.pli" 
 1894  module "/pliant/graphic/image/antialiasing.pli" 
 1895  module "/pliant/graphic/color/gamut.pli" 
 1896  module "outline.pli" 
 1897   
 1898   
 1899  method img character f char_num t color 
 1900    oarg_rw ImagePrototype img ; arg Font f ; arg Int char_num ; arg Transform2 t ; arg Address color 
 1901    var Pointer:FontChar ch :> f:chars first char_num 
 1902    if exists:ch 
 1903      img fill ch:curves outline_evenodd color 
 1904    eif auto_accent and { var Pointer:FontAccent :> accents first char_num ; exists a } 
 1905      var Pointer:FontChar base :> f:chars first a:base 
 1906      var Pointer:FontChar accent :> f:chars first a:accent 
 1907      if exists:base and exists:accent 
 1908        img fill base:curves outline_evenodd color 
 1909        img fill accent:curves outline_evenodd color 
 1910     
 1911     
 1912  if raster_fonts 
 1913   
 1914    method f rasterize1 char_num rsize -> buf 
 1915      arg Font f ; arg Int char_num ; arg Int rsize ; arg Address buf 
 1916      var Float res := rsize/(f:bbox_y1-f:bbox_y0) 
 1917      var Int aa := 4 
 1918      var Int threshold := aa*aa\2 
 1919      var Link:ImagePixmap pixmap :> new ImagePixmap 
 1920      pixmap setup (image_prototype f:bbox_x0 f:bbox_y0 f:bbox_x1 f:bbox_y1 (cast (f:bbox_x1-f:bbox_x0)*res Int)*aa (cast (f:bbox_y1-f:bbox_y0)*res Int)*aa color_gamut:"grey""" 
 1921      var Link:ImageAntiAliasing final :> new ImageAntiAliasing 
 1922      final bind pixmap aa aa 
 1923      var Address linebuf := memory_allocate final:line_size null 
 1924      var uInt8 color := 0 
 1925      for (var Int y) pixmap:size_y-1 
 1926        pixmap fill pixmap:size_x addressof:color 
 1927      var uInt8 color := aa*aa 
 1928      pixmap character char_num transform addressof:color 
 1929      var Int reserved := 2*rsize*3+uInt:size ; var Int used := 0 
 1930      buf := memory_allocate reserved null 
 1931      var Int cx := (cast -(f:bbox_x0)*res Int) ; var Int cy := (cast -(f:bbox_y0)*res Int) 
 1932      for (var Int y) final:size_y-1 
 1933        final read final:size_x linebuf 
 1934        var Int x0 := 0 
 1935        part segment 
 1936          while x0<final:size_x and (linebuf map uInt8 x0)<threshold 
 1937            x0 += 1 
 1938          if x0=final:size_x 
 1939            leave segment 
 1940          var Int x1 := x0 
 1941          while x1<final:size_x and (linebuf map uInt8 x1)>=threshold 
 1942            x1 += 1 
 1943          if used+3+uInt:size>reserved 
 1944            reserved *= 2 
 1945            buf := memory_resize buf reserved addressof:f 
 1946          var Int limit := 127 
 1947          var Int dx := x0-cx 
 1948          var Int dy := y-cy 
 1949          if dx<>(bound dx -limit limit) 
 1950            dx := bound dx -limit limit ; x1 := x0 
 1951          if dy<>(bound dy -limit limit) 
 1952            dy := bound dy -limit limit ; x1 := x0 
 1953          (buf translate Byte used) map Int8 := dx ; used += 1 
 1954          (buf translate Byte used) map Int8 := dy ; used += 1 
 1955          (buf translate Byte used) map uInt8 := x1-x0 ; used += 1 
 1956          cx += dx ; cy += dy 
 1957          x0 := x1 
 1958          restart segment 
 1959      memory_free linebuf 
 1960      (buf translate Byte used) map uInt := 0 ; used += uInt size 
 1961      buf := memory_resize buf used addressof:f 
 1962       
 1963    method img rcharacter1 buf ix iy color 
 1964      oarg_rw ImagePrototype img ; arg Address buf ; arg Int ix iy ; arg Address color 
 1965      var Address := buf ; var Int := ix ; var Int := iy 
 1966      while (map uInt)<>0 
 1967        += map Int8 ; := translate Int8 1 
 1968        += map Int8 ; := translate Int8 1 
 1969        var Int := map uInt8 ; := translate uInt8 1 
 1970        if y>=and y<img:size_y 
 1971          var Int x0 := max 0 
 1972          var Int x1 := min x+img:size_x 
 1973          if x1>x0 
 1974            img fill x0 x1-x0 color 
 1975     
 1976     
 1977    function pixel_mixte pixel color pixel_size opacity 
 1978      arg Address pixel color ; arg Int pixel_size opacity 
 1979      for (var Int i) pixel_size-1 
 1980        pixel map uInt8 := ((pixel map uInt8 i)*(255-opacity)+(color map uInt8 i)*opacity)\255 
 1981     
 1982    method f rasterize2 char_num rsize -> buf 
 1983      arg Font f ; arg Int char_num ; arg Int rsize ; arg Address buf 
 1984      var Float res := rsize/(f:bbox_y1-f:bbox_y0) 
 1985      var Link:ImagePixmap pixmap :> new ImagePixmap 
 1986      pixmap setup (image_prototype f:bbox_x0 f:bbox_y0 f:bbox_x1 f:bbox_y1 (cast (f:bbox_x1-f:bbox_x0)*res Int)*raster_anti_aliasing (cast (f:bbox_y1-f:bbox_y0)*res Int)*raster_anti_aliasing color_gamut:"grey""" 
 1987      var Link:ImageAntiAliasing final :> new ImageAntiAliasing 
 1988      final bind pixmap raster_anti_aliasing raster_anti_aliasing 
 1989      var Address linebuf := memory_allocate final:line_size null 
 1990      var uInt8 color := 0 
 1991      for (var Int y) pixmap:size_y-1 
 1992        pixmap fill pixmap:size_x addressof:color 
 1993      var uInt8 color := 255 
 1994      pixmap character char_num transform addressof:color 
 1995      var Int reserved := 2*rsize*3+uInt:size ; var Int used := 0 
 1996      buf := memory_allocate reserved null 
 1997      var Int cx := (cast -(f:bbox_x0)*res Int) ; var Int cy := (cast -(f:bbox_y0)*res Int) 
 1998      for (var Int y) final:size_y-1 
 1999        final read final:size_x linebuf 
 2000        var Int x0 := 0 
 2001        part segment 
 2002          while x0<final:size_x and (linebuf map uInt8 x0)=0 
 2003            x0 += 1 
 2004          if x0=final:size_x 
 2005            leave segment 
 2006          var Int x1 := x0 
 2007          while x1<final:size_x and (linebuf map uInt8 x1)<>0 
 2008            x1 += 1 
 2009          while used+3+(x1-x0)+uInt:size>reserved 
 2010            reserved *= 2 
 2011            buf := memory_resize buf reserved addressof:f 
 2012          var Int limit := 127 
 2013          var Int dx := x0-cx 
 2014          var Int dy := y-cy 
 2015          if dx<>(bound dx -limit limit) 
 2016            dx := bound dx -limit limit ; x1 := x0 
 2017          if dy<>(bound dy -limit limit) 
 2018            dy := bound dy -limit limit ; x1 := x0 
 2019          (buf translate Byte used) map Int8 := dx ; used += 1 
 2020          (buf translate Byte used) map Int8 := dy ; used += 1 
 2021          (buf translate Byte used) map uInt8 := x1-x0 ; used += 1 
 2022          for (var Int x) x0 x1-1 
 2023            (buf translate Byte used) map uInt8 := linebuf map uInt8 x ; used += 1 
 2024          cx += dx ; cy += dy 
 2025          x0 := x1 
 2026          restart segment 
 2027      memory_free linebuf 
 2028      (buf translate Byte used) map uInt := 0 ; used += uInt size 
 2029      buf := memory_resize buf used addressof:f 
 2030       
 2031    method img rcharacter2 buf ix iy color 
 2032      oarg_rw ImagePrototype img ; arg Address buf ; arg Int ix iy ; arg Address color 
 2033      var Address := buf ; var Int := ix ; var Int := iy 
 2034      var Int psize := img pixel_size 
 2035      while (map uInt)<>0 
 2036        += map Int8 ; := translate Int8 1 
 2037        += map Int8 ; := translate Int8 1 
 2038        var Int := map uInt8 ; := translate uInt8 1 
 2039        if y>=and y<img:size_y 
 2040          var Int x0 := max 0 
 2041          var Int x1 := min x+img:size_x 
 2042          if x1>x0 
 2043            var Address adr := img write_map x0 x1-x0 x1-x0 (var Int count) 
 2044            if adr<>null 
 2045              var Address pixel := adr ; var Address stop := pixel translate Byte (x1-x0)*psize 
 2046              var Address opacity := translate uInt8 x0-x 
 2047              while pixel<>stop 
 2048                pixel_mixte pixel color psize (opacity map uInt8) 
 2049                pixel := pixel translate Byte psize 
 2050                opacity := opacity translate uInt8 1 
 2051              img write_unmap x0 count adr 
 2052        := translate uInt8 n 
 2053   
 2054   
 2055    method f rasterize char_num rsize level -> buf 
 2056      arg Font f ; arg Int char_num ; arg Int rsize level ; arg Address buf 
 2057      if level=1 
 2058        buf := rasterize1 char_num rsize 
 2059      else 
 2060        buf := rasterize2 char_num rsize 
 2061   
 2062    method img rcharacter buf ix iy color level 
 2063      oarg_rw ImagePrototype img ; arg Address buf ; arg Int ix iy ; arg Address color ; arg Int level 
 2064      if level=1 
 2065        img rcharacter1 buf ix iy color 
 2066      else 
 2067        img rcharacter2 buf ix iy color 
 2068   
 2069   
 2070  method p index_x x -> i 
 2071    arg ImagePrototype p ; arg Float x ; arg Int i 
 2072    := cast (x-p:x0)/(p:x1-p:x0)*p:size_x-0.499 Int 
 2073   
 2074  method p index_y y -> i 
 2075    arg ImagePrototype p ; arg Float y ; arg Int i 
 2076    := cast (y-p:y0)/(p:y1-p:y0)*p:size_y-0.499 Int 
 2077   
 2078  method img text buffer count csize f kerning t color speedup 
 2079    oarg_rw ImagePrototype img ; arg Address buffer ; arg Int count csize ; arg_rw Font f ; arg Address kerning ; arg Transform2 t ; arg Address color ; arg Int speedup 
 2080    if raster_fonts 
 2081      var CBool raster := false 
 2082      if speedup>and t:level<=transform_scale and t:xx=t:yy 
 2083        var Int rsize := cast t:yy*(f:bbox_y1-f:bbox_y0)/(img:y1-img:y0)*img:size_y Int 
 2084        if rsize<=raster_maximum_size 
 2085          var Link:FontRaster rf 
 2086          if (cache_open "/pliant/fontr"+string:speedup+"/"+string:rsize+"/"+f:id FontRaster ((addressof Link:FontRaster rf) map Link:CachePrototype)) 
 2087            cache_ready ((addressof Link:FontRaster rf) map Link:CachePrototype) 
 2088          rf:sem request 
 2089          raster := true 
 2090    var Transform2 cur := t 
 2091    for (var Int i) count-1 
 2092      if kerning<>null 
 2093        var Vector2 := cur (kerning map Float i)*f:vector ; cur xt += x ; cur yt += y 
 2094      var Int num 
 2095      if csize=1 
 2096        num := buffer map uInt8 i 
 2097      eif csize=4 
 2098        num := buffer map Int32 i 
 2099      if raster_fonts and raster 
 2100        var Pointer:FontChar ch :> f:chars first num 
 2101        if exists:ch # and cur_x+f:x0<img:x1 and cur_x+f:x1>img:x0 and cur_y+f:y0<img:y1 and cur_y+f:y1>img:y0 
 2102          var Pointer:Address rch :> rf:chars first num 
 2103          if not exists:rch 
 2104            rf:chars insert num (rasterize num rsize speedup) 
 2105            rch :> rf:chars first num 
 2106          img rcharacter rch (img index_x cur:xt) (img index_y cur:yt) color speedup 
 2107        eif auto_accent and { var Pointer:FontAccent :> accents first num ; exists a } 
 2108          var Pointer:FontChar base :> f:chars first a:base 
 2109          var Pointer:FontChar accent :> f:chars first a:accent 
 2110          if exists:base and exists:accent 
 2111            var Pointer:Address rch :> rf:chars first a:base 
 2112            if not exists:rch 
 2113              rf:chars insert a:base (rasterize a:base rsize speedup) 
 2114              rch :> rf:chars first a:base 
 2115            img rcharacter rch (img index_x cur:xt) (img index_y cur:yt) color speedup 
 2116            var Pointer:Address rch :> rf:chars first a:accent 
 2117            if not exists:rch 
 2118              rf:chars insert a:accent (rasterize a:accent rsize speedup) 
 2119              rch :> rf:chars first a:accent 
 2120            img rcharacter rch (img index_x cur:xt) (img index_y cur:yt) color speedup 
 2121      else 
 2122        img character num cur color 
 2123      var Vector2 := cur (vector num) ; cur xt += x ; cur yt += y 
 2124    if raster_fonts and raster 
 2125      rf:sem release 
 2126   
 2127  method img text txt f kerning t color 
 2128    oarg_rw ImagePrototype img ; arg Str txt ; arg Font f ; arg Address kerning ; arg Transform2 t ; arg Address color 
 2129    img text txt:characters txt:len 1 (addressof:map Font) kerning color 0 
 2130   
 2131  method img text txt f kerning t color 
 2132    oarg_rw ImagePrototype img ; arg Str32 txt ; arg Font f ; arg Address kerning ; arg Transform2 t ; arg Address color 
 2133    img text txt:characters txt:len 4 (addressof:map Font) kerning color 0 
 2134   
 2135  method img text txt f kerning t color speedup 
 2136    oarg_rw ImagePrototype img ; arg Str txt ; arg Font f ; arg Address kerning ; arg Transform2 t ; arg Address color ; arg Int speedup 
 2137    img text txt:characters txt:len 1 (addressof:map Font) kerning color speedup 
 2138   
 2139  method img text txt f kerning t color speedup 
 2140    oarg_rw ImagePrototype img ; arg Str32 txt ; arg Font f ; arg Address kerning ; arg Transform2 t ; arg Address color ; arg Int speedup 
 2141    img text txt:characters txt:len 4 (addressof:map Font) kerning color speedup 
 2142   
 2143  export '. character' '. text' 
 2144   
 2145   
 2146 
 
 2147  # Font caching 
 2148   
 2149   
 2150  module "/pliant/storage/database.pli" 
 2151  module "/pliant/admin/file.pli" 
 2152   
 2153   
 2154  public 
 2155   
 2156    type FontFile 
 2157      field Str family 
 2158      field Str fullname 
 2159      field Str psname 
 2160      field Str file 
 2161      field Str options 
 2162   
 2163    type FontDatabase 
 2164      field Set:FontFile font # key is md5 
 2165      field (Set Set:Void) family 
 2166      field Set:Str fullname 
 2167      field Set:Str psname 
 2168      field Set:Str alias 
 2169     
 2170    (gvar Database:FontDatabase font_database) load "security:/font.pdb" mount "/pliant/font" 
 2171   
 2172   
 2173  function font_scan path 
 2174    arg Str path 
 2175    var Array:FileInfo files := file_list path extended+recursive 
 2176    for (var Int i) files:size-1 
 2177      if files:i:extension=".pfb" and not files:i:is_link 
 2178        var Link:Font :> font_postscript files:i:name "" 
 2179        if exists:f 
 2180          font_database:data:font create f:id 
 2181          var Data:FontFile ffile :> font_database:data:font f:id 
 2182          ffile family := family 
 2183          ffile fullname := fullname 
 2184          ffile psname := psname 
 2185          ffile file := file 
 2186          console f:fullname eol 
 2187          font_database:data:family create f:family 
 2188          (font_database:data:family f:family) create f:id 
 2189          font_database:data:fullname create f:fullname 
 2190          font_database:data:fullname f:fullname := id 
 2191          font_database:data:psname create f:psname 
 2192          font_database:data:psname f:psname := id 
 2193   
 2194   
 2195  function font name -> font 
 2196    arg Str name ; arg Link:Font font 
 2197    var Data:FontFile :> font_database:data:font name # md5 
 2198    if not exists:f 
 2199      :> font_database:data:font font_database:data:psname:name 
 2200    if not exists:f 
 2201      :> font_database:data:font font_database:data:fullname:name 
 2202    if not exists:f 
 2203      :> font_database:data:font font_database:data:alias:name 
 2204    if exists:f 
 2205      if (cache_open "/pliant/font/"+keyof:Font ((addressof Link:Font font) map Link:CachePrototype)) 
 2206        if (font load_postscript f:file f:options)=success 
 2207          cache_ready ((addressof Link:Font font) map Link:CachePrototype) 
 2208        else 
 2209          cache_cancel ((addressof Link:Font font) map Link:CachePrototype) 
 2210          font :> null map Font 
 2211    else 
 2212      font :> null map Font 
 2213   
 2214   
 2215  export font_scan font 
 2216   
 2217   
 2218   
 2219